1*6ba597c5SAnurag S. MaskeyCDDL HEADER START 2*6ba597c5SAnurag S. Maskey 3*6ba597c5SAnurag S. MaskeyThe contents of this file are subject to the terms of the 4*6ba597c5SAnurag S. MaskeyCommon Development and Distribution License (the "License"). 5*6ba597c5SAnurag S. MaskeyYou may not use this file except in compliance with the License. 6*6ba597c5SAnurag S. Maskey 7*6ba597c5SAnurag S. MaskeyYou can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 8*6ba597c5SAnurag S. Maskeyor http://www.opensolaris.org/os/licensing. 9*6ba597c5SAnurag S. MaskeySee the License for the specific language governing permissions 10*6ba597c5SAnurag S. Maskeyand limitations under the License. 11*6ba597c5SAnurag S. Maskey 12*6ba597c5SAnurag S. MaskeyWhen distributing Covered Code, include this CDDL HEADER in each 13*6ba597c5SAnurag S. Maskeyfile and include the License file at usr/src/OPENSOLARIS.LICENSE. 14*6ba597c5SAnurag S. MaskeyIf applicable, add the following below this CDDL HEADER, with the 15*6ba597c5SAnurag S. Maskeyfields enclosed by brackets "[]" replaced with your own identifying 16*6ba597c5SAnurag S. Maskeyinformation: Portions Copyright [yyyy] [name of copyright owner] 17*6ba597c5SAnurag S. Maskey 18*6ba597c5SAnurag S. MaskeyCDDL HEADER END 19*6ba597c5SAnurag S. Maskey 20*6ba597c5SAnurag S. MaskeyCopyright 2010 Sun Microsystems, Inc. All rights reserved. 21*6ba597c5SAnurag S. MaskeyUse is subject to license terms. 22*6ba597c5SAnurag S. Maskey 23*6ba597c5SAnurag S. MaskeyImplementation Overview for the NetWork AutoMagic daemon 24*6ba597c5SAnurag S. MaskeyJohn Beck, Renee Danson, Michael Hunter, Alan Maguire, Kacheong Poon, 25*6ba597c5SAnurag S. MaskeyGarima Tripathi, Jan Xie, Anurag Maskey 26*6ba597c5SAnurag S. Maskey[Structure and some content shamelessly stolen from Peter Memishian's 27*6ba597c5SAnurag S. Maskeydhcpagent architecture overview.] 28*6ba597c5SAnurag S. Maskey 29*6ba597c5SAnurag S. MaskeyINTRODUCTION 30*6ba597c5SAnurag S. Maskey============ 31*6ba597c5SAnurag S. Maskey 32*6ba597c5SAnurag S. MaskeyDetails about the NWAM requirements, architecture, and design are 33*6ba597c5SAnurag S. Maskeyavailable via the NWAM opensolaris project at 34*6ba597c5SAnurag S. Maskeyhttp://opensolaris.org/os/project/nwam. The point of this document is 35*6ba597c5SAnurag S. Maskeyto place details relevant to somebody attempting to understand the 36*6ba597c5SAnurag S. Maskeyimplementation close to the source code. 37*6ba597c5SAnurag S. Maskey 38*6ba597c5SAnurag S. MaskeyTHE BASICS 39*6ba597c5SAnurag S. Maskey========== 40*6ba597c5SAnurag S. Maskey 41*6ba597c5SAnurag S. MaskeySOURCE FILE ORGANIZATION 42*6ba597c5SAnurag S. Maskey======================= 43*6ba597c5SAnurag S. Maskeyevent sources: 44*6ba597c5SAnurag S. Maskey dlpi_events.c 45*6ba597c5SAnurag S. Maskey routing_events.c 46*6ba597c5SAnurag S. Maskey sysevent_events.c 47*6ba597c5SAnurag S. Maskey 48*6ba597c5SAnurag S. Maskeyobject-specific event handlers: 49*6ba597c5SAnurag S. Maskey enm.c 50*6ba597c5SAnurag S. Maskey known_wlans.c 51*6ba597c5SAnurag S. Maskey loc.c 52*6ba597c5SAnurag S. Maskey ncp.c 53*6ba597c5SAnurag S. Maskey ncu_ip.c 54*6ba597c5SAnurag S. Maskey ncu_phys.c 55*6ba597c5SAnurag S. Maskey 56*6ba597c5SAnurag S. Maskeylegacy config upgrade 57*6ba597c5SAnurag S. Maskey llp.c 58*6ba597c5SAnurag S. Maskey 59*6ba597c5SAnurag S. Maskeygeneric code: 60*6ba597c5SAnurag S. Maskey objects.c 61*6ba597c5SAnurag S. Maskey events.c 62*6ba597c5SAnurag S. Maskey conditions.c 63*6ba597c5SAnurag S. Maskey logging.c 64*6ba597c5SAnurag S. Maskey util.c 65*6ba597c5SAnurag S. Maskey 66*6ba597c5SAnurag S. Maskeynwam door requests: 67*6ba597c5SAnurag S. Maskey door_if.c 68*6ba597c5SAnurag S. Maskey 69*6ba597c5SAnurag S. Maskeyentry point: 70*6ba597c5SAnurag S. Maskey main.c 71*6ba597c5SAnurag S. Maskey 72*6ba597c5SAnurag S. MaskeyOVERVIEW 73*6ba597c5SAnurag S. Maskey======== 74*6ba597c5SAnurag S. Maskey 75*6ba597c5SAnurag S. MaskeyHere we discuss the essential objects and subtle aspects of the NWAM 76*6ba597c5SAnurag S. Maskeydaemon implementation. Note that there is of course much more that is 77*6ba597c5SAnurag S. Maskeynot discussed here, but after this overview you should be able to fend 78*6ba597c5SAnurag S. Maskeyfor yourself in the source code. 79*6ba597c5SAnurag S. Maskey 80*6ba597c5SAnurag S. MaskeyEvents and Objects 81*6ba597c5SAnurag S. Maskey================== 82*6ba597c5SAnurag S. Maskey 83*6ba597c5SAnurag S. MaskeyEvents come to NWAM from a variety of different sources asyncronously. 84*6ba597c5SAnurag S. Maskey 85*6ba597c5SAnurag S. Maskeyo routing socket 86*6ba597c5SAnurag S. Maskeyo dlpi 87*6ba597c5SAnurag S. Maskeyo sysevents 88*6ba597c5SAnurag S. Maskeyo doors 89*6ba597c5SAnurag S. Maskey 90*6ba597c5SAnurag S. MaskeyRouting sockets and dlpi (DL_NOTE_LINK_UP|DOWN events) are handled by 91*6ba597c5SAnurag S. Maskeydedicated threads. Sysevents and doors are both seen as callbacks into 92*6ba597c5SAnurag S. Maskeythe process proper and will often post their results to the main event 93*6ba597c5SAnurag S. Maskeyqueue. All event sources post events onto the main event queue. In 94*6ba597c5SAnurag S. Maskeyaddition state changes of objects and door requests (requesting current 95*6ba597c5SAnurag S. Maskeystate or a change of state, specification of a WiFi key etc) can 96*6ba597c5SAnurag S. Maskeylead to additional events. We have daemon-internal events (object 97*6ba597c5SAnurag S. Maskeyinitialization, periodic state checks) which are simply enqueued 98*6ba597c5SAnurag S. Maskeyon the event queue, and external events which are both enqueued on 99*6ba597c5SAnurag S. Maskeythe event queue and sent to registered listeners (via nwam_event_send()). 100*6ba597c5SAnurag S. Maskey 101*6ba597c5SAnurag S. MaskeySo the structure of the daemon is a set of threads that drive event 102*6ba597c5SAnurag S. Maskeygeneration. Events are posted either directly onto the event queue 103*6ba597c5SAnurag S. Maskeyor are delayed by posting onto the pending event queue. SIGALARMs 104*6ba597c5SAnurag S. Maskeyare set for the event delay, and when the SIGALARM is received 105*6ba597c5SAnurag S. Maskeypending events that have expired are moved onto the event queue 106*6ba597c5SAnurag S. Maskeyproper. Delayed enqueueing is useful for periodic checks. 107*6ba597c5SAnurag S. Maskey 108*6ba597c5SAnurag S. MaskeyDecisions to change conditions based upon object state changes are 109*6ba597c5SAnurag S. Maskeydelayed until after bursts of events. This is achieved by marking a 110*6ba597c5SAnurag S. Maskeyflag when it is deemed checking is necessary and then the next time the 111*6ba597c5SAnurag S. Maskeyqueue is empty performing those checks. A typical event profile will 112*6ba597c5SAnurag S. Maskeybe one event (e.g. a link down) causing a flurry of other events (e.g. 113*6ba597c5SAnurag S. Maskeyrelated interface down). By waiting until all the consequences of the 114*6ba597c5SAnurag S. Maskeyinitial event have been carried out to make higher level decisions we 115*6ba597c5SAnurag S. Maskeyimplicitly debounce those higher level decisions. 116*6ba597c5SAnurag S. Maskey 117*6ba597c5SAnurag S. MaskeyAt the moment queue quiet actually means that the queue has been quiet 118*6ba597c5SAnurag S. Maskeyfor some short period of time (.1s). Typically the flurry of events we 119*6ba597c5SAnurag S. Maskeywant to work through are internally generated and are back to back in 120*6ba597c5SAnurag S. Maskeythe queue. We wait a bit longer in case there are reprucussions from 121*6ba597c5SAnurag S. Maskeywhat we do that cause external events to be posted on us. We are not 122*6ba597c5SAnurag S. Maskeyinterested in waiting for longer term things to happen but merely to 123*6ba597c5SAnurag S. Maskeycatch immediate changes. 124*6ba597c5SAnurag S. Maskey 125*6ba597c5SAnurag S. MaskeyWhen running, the daemon will consist of a number of threads: 126*6ba597c5SAnurag S. Maskey 127*6ba597c5SAnurag S. Maskeyo the event handling thread: a thread blocking until events appear on the 128*6ba597c5SAnurag S. Maskey event queue, processing each event in order. Events that require 129*6ba597c5SAnurag S. Maskey time-consuming processing are spawned in worker threads (e.g. WiFi 130*6ba597c5SAnurag S. Maskey connect, DHCP requests etc). 131*6ba597c5SAnurag S. Maskeyo door request threads: the door infrastructure manages server threads 132*6ba597c5SAnurag S. Maskey which process synchronous NWAM client requests (e.g. get state of an 133*6ba597c5SAnurag S. Maskey object, connect to a specific WLAN, initiate a scan on a link etc). 134*6ba597c5SAnurag S. Maskeyo various wifi/IP threads: threads which do asynchronous work such as 135*6ba597c5SAnurag S. Maskey DHCP requests, WLAN scans etc that cannot hold up event processing in 136*6ba597c5SAnurag S. Maskey the main event handling thread. 137*6ba597c5SAnurag S. Maskeyo routing socket threads: process routing socket messages of interest 138*6ba597c5SAnurag S. Maskey (address additons/deletions) and package them as NWAM messages. 139*6ba597c5SAnurag S. Maskeyo dlpi threads: used to monitor for DL_NOTE_LINK messages on links 140*6ba597c5SAnurag S. Maskey 141*6ba597c5SAnurag S. MaskeyThe daemon is structured around a set of objects representing NCPs[1], 142*6ba597c5SAnurag S. MaskeyNCUs[2], ENMs[3] and known WLANs and a set of state machines which 143*6ba597c5SAnurag S. Maskeyconsume events which act on those objects. Object lists are maintained 144*6ba597c5SAnurag S. Maskeyfor each object type, and these contain both a libnwam handle (to allow 145*6ba597c5SAnurag S. Maskeyreading the object directly) and an optional object data pointer which 146*6ba597c5SAnurag S. Maskeycan point to state information used to configure the object. 147*6ba597c5SAnurag S. Maskey 148*6ba597c5SAnurag S. MaskeyEvents can be associated with specific objects (e.g. link up), or associated 149*6ba597c5SAnurag S. Maskeywith no object in particular (e.g. shutdown). 150*6ba597c5SAnurag S. Maskey 151*6ba597c5SAnurag S. MaskeyEach object type registers a set of event handler functions with the event 152*6ba597c5SAnurag S. Maskeyframework such that when an event occurs, the appropriate handler for the 153*6ba597c5SAnurag S. Maskeyobject type is used. The event handlers are usually called 154*6ba597c5SAnurag S. Maskeynwamd_handle_*_event(). 155*6ba597c5SAnurag S. Maskey 156*6ba597c5SAnurag S. Maskey[1] NCP Network Configuration Profile; the set of link- and IP-layer 157*6ba597c5SAnurag S. Maskeyconfiguration units which collectively specify how a system should be 158*6ba597c5SAnurag S. Maskeyconnected to the network 159*6ba597c5SAnurag S. Maskey 160*6ba597c5SAnurag S. Maskey[2] NCU Network Configuration Unit; the individual components of an NCP 161*6ba597c5SAnurag S. Maskey 162*6ba597c5SAnurag S. Maskey[3] ENM External Network Modifiers; user executable scripts often used 163*6ba597c5SAnurag S. Maskeyto configure a VPN 164*6ba597c5SAnurag S. Maskey 165*6ba597c5SAnurag S. MaskeyDoors and External Events 166*6ba597c5SAnurag S. Maskey========================= 167*6ba597c5SAnurag S. Maskey 168*6ba597c5SAnurag S. MaskeyThe command interface to nwamd is thread a door at NWAM_DOOR 169*6ba597c5SAnurag S. Maskey(/etc/svc/volatile/nwam/nwam_door). This door allows external program to send 170*6ba597c5SAnurag S. Maskeymessages to nwamd. The way doors work is to provide a mechanism for 171*6ba597c5SAnurag S. Maskeyanother process to execute code in your process space. This looks like 172*6ba597c5SAnurag S. Maskeya CSPish send/receive/reply in that the receiving process provide a 173*6ba597c5SAnurag S. Maskeysyncronization point (via door_create(3C)), the calling process uses 174*6ba597c5SAnurag S. Maskeythat syncronization point to rendezvous with and provide arguments (via 175*6ba597c5SAnurag S. Maskeydoor_call(3C), and then the receive process reply (via 176*6ba597c5SAnurag S. Maskeydoor_return(3C))) passing back data as required. The OS makes it such 177*6ba597c5SAnurag S. Maskeythat the memory used to pass data via door_call(3C) is mapped into the 178*6ba597c5SAnurag S. Maskeyreceiving process which can write back into it and then transparently 179*6ba597c5SAnurag S. Maskeyhave it mapped back to the calling process. 180*6ba597c5SAnurag S. Maskey 181*6ba597c5SAnurag S. MaskeyAs well as handling internal events of interest, the daemon also needs 182*6ba597c5SAnurag S. Maskeyto send events of interest (link up/down, WLAN scan/connect results etc) 183*6ba597c5SAnurag S. Maskeyto (possibly) multiple NWAM client listeners. This is done via 184*6ba597c5SAnurag S. MaskeySystem V message queues. On registering for events via a libnwam door 185*6ba597c5SAnurag S. Maskeyrequest into the daemon (nwam_events_register()), a per-client 186*6ba597c5SAnurag S. Maskey(identified by pid) message queue file is created. The 187*6ba597c5SAnurag S. Maskeydaemon sends messages to all listeners by examining the list of 188*6ba597c5SAnurag S. Maskeymessage queue files (allowing registration to be robust across 189*6ba597c5SAnurag S. Maskeydaemon restarts) and sending events to each listener. This is done 190*6ba597c5SAnurag S. Maskeyvia the libnwam function nwam_event_send() which hides the IPC 191*6ba597c5SAnurag S. Maskeymechanism from the daemon. 192*6ba597c5SAnurag S. Maskey 193*6ba597c5SAnurag S. MaskeyObjects 194*6ba597c5SAnurag S. Maskey======= 195*6ba597c5SAnurag S. MaskeyFour object lists are maintained within the daemon - one each for 196*6ba597c5SAnurag S. Maskeythe configuration objects libnwam manages. i.e.: 197*6ba597c5SAnurag S. Maskey 198*6ba597c5SAnurag S. Maskeyo ENMs 199*6ba597c5SAnurag S. Maskeyo locations 200*6ba597c5SAnurag S. Maskeyo known WLANs 201*6ba597c5SAnurag S. Maskeyo NCUs of the current active NCP 202*6ba597c5SAnurag S. Maskey 203*6ba597c5SAnurag S. MaskeyObjects have an associated libnwam handle and an optional data 204*6ba597c5SAnurag S. Maskeyfield (which is used for NCUs only). 205*6ba597c5SAnurag S. Maskey 206*6ba597c5SAnurag S. MaskeyLocking is straightforward - nwamd_object_init() will initialize 207*6ba597c5SAnurag S. Maskeyan object of a particular type in the appropriate object list, 208*6ba597c5SAnurag S. Maskeyreturning it with the object lock held. When it is no longer needed, 209*6ba597c5SAnurag S. Maskeynwamd_object_unlock() should be called on the object. 210*6ba597c5SAnurag S. Maskey 211*6ba597c5SAnurag S. MaskeyTo retrieve an existing object, nwamd_object_find() should be 212*6ba597c5SAnurag S. Maskeycalled - again this returns the object in a locked state. 213*6ba597c5SAnurag S. Maskey 214*6ba597c5SAnurag S. Maskeynwamd_object_lock() is deliberately not exposed outside of objects.c, 215*6ba597c5SAnurag S. Maskeysince object locking is implicit in the above creation/retrieval 216*6ba597c5SAnurag S. Maskeyfunctions. 217*6ba597c5SAnurag S. Maskey 218*6ba597c5SAnurag S. MaskeyAn object is removed from the object list (with handle destroyed) 219*6ba597c5SAnurag S. Maskeyvia nwamd_object_fini() - the object data (if any) is returned 220*6ba597c5SAnurag S. Maskeyfrom this call to allow deallocation. 221*6ba597c5SAnurag S. Maskey 222*6ba597c5SAnurag S. MaskeyObject state 223*6ba597c5SAnurag S. Maskey============ 224*6ba597c5SAnurag S. Maskeynwamd deals with 3 broad types of object that need to maintain 225*6ba597c5SAnurag S. Maskeyinternal state: NCUs, ENMs and locations (known WLANs are configuration 226*6ba597c5SAnurag S. Maskeyobjects but don't have a state beyond simply being present). 227*6ba597c5SAnurag S. MaskeyNWAM objects all share a basic set of states: 228*6ba597c5SAnurag S. Maskey 229*6ba597c5SAnurag S. MaskeyState Description 230*6ba597c5SAnurag S. Maskey===== =========== 231*6ba597c5SAnurag S. Maskeyuninitialized object representation not present on system or in nwamd 232*6ba597c5SAnurag S. Maskeyinitialized object representation present in system and in nwamd 233*6ba597c5SAnurag S. Maskeydisabled disabled manually 234*6ba597c5SAnurag S. Maskeyoffline external conditions are not satisfied 235*6ba597c5SAnurag S. Maskeyoffline* external conditions are satisfied, trying to move online 236*6ba597c5SAnurag S. Maskeyonline* external conditions no longer satisfied, trying to move offline 237*6ba597c5SAnurag S. Maskeyonline conditions satisfied and configured 238*6ba597c5SAnurag S. Maskeymaintenance error occurred in applying configuration 239*6ba597c5SAnurag S. Maskey 240*6ba597c5SAnurag S. MaskeyThese deliberately mimic SMF states. 241*6ba597c5SAnurag S. Maskey 242*6ba597c5SAnurag S. MaskeyThe states of interest are offline, offline* and online. 243*6ba597c5SAnurag S. Maskey 244*6ba597c5SAnurag S. MaskeyAn object (link/interface NCU, ENM or location) should only move online 245*6ba597c5SAnurag S. Maskeywhen its conditions are satisfied _and_ its configuration has been successfully 246*6ba597c5SAnurag S. Maskeyapplied. This occurs when an ENM method has run or a link is up, or an 247*6ba597c5SAnurag S. Maskeyinterface has at least one address assigned. 248*6ba597c5SAnurag S. Maskey 249*6ba597c5SAnurag S. MaskeyTo understand the distinction between offline and offline*, consider the case 250*6ba597c5SAnurag S. Maskeywhere a link is of prioritized activation, and either is a lower priority 251*6ba597c5SAnurag S. Maskeygroup - and hence inactive (due to cable being unplugged or inability to 252*6ba597c5SAnurag S. Maskeyconnect to wifi) - or a higher priority group - and hence active. In general, 253*6ba597c5SAnurag S. Maskeywe want to distinguish between two cases: 254*6ba597c5SAnurag S. Maskey 255*6ba597c5SAnurag S. Maskey1) when we are actively configuring the link with a view to moving online 256*6ba597c5SAnurag S. Maskey(offline*), as would be the case when the link's priority group is 257*6ba597c5SAnurag S. Maskeyactive. 258*6ba597c5SAnurag S. Maskey2) when external policy-based conditions prevent a link from being active. 259*6ba597c5SAnurag S. Maskeyoffline should be used for such cases. Links in priority groups above and 260*6ba597c5SAnurag S. Maskeybelow the currently-active group will be offline, since policy precludes them 261*6ba597c5SAnurag S. Maskeyfrom activating (as less-prioritized links). 262*6ba597c5SAnurag S. Maskey 263*6ba597c5SAnurag S. MaskeySo we see that offline and offline* can thus be used to distinguish between 264*6ba597c5SAnurag S. Maskeycases that have the potentiality to move online (offline*) from a policy 265*6ba597c5SAnurag S. Maskeyperspective - i.e. conditions on the location allow it, or link prioritization 266*6ba597c5SAnurag S. Maskeyallows it - and cases where external conditions dictate that it should not 267*6ba597c5SAnurag S. Maskey(offline). 268*6ba597c5SAnurag S. Maskey 269*6ba597c5SAnurag S. MaskeyOnce an object reaches offline*, its configuration processes should kick in. 270*6ba597c5SAnurag S. MaskeyThis is where auxiliary state is useful, as it allows us to distinguish between 271*6ba597c5SAnurag S. Maskeyvarious states in that configuration process. For example, a link can be 272*6ba597c5SAnurag S. Maskeywaiting for WLAN selection or key data, or an interface can be waiting for 273*6ba597c5SAnurag S. MaskeyDHCP response. This auxiliary state can then also be used diagnostically by 274*6ba597c5SAnurag S. Maskeylibnwam consumers to determine the current status of a link, interface, ENM 275*6ba597c5SAnurag S. Maskeyetc. 276*6ba597c5SAnurag S. Maskey 277*6ba597c5SAnurag S. MaskeyWiFi links present a problem however. On the one hand, we want them 278*6ba597c5SAnurag S. Maskeyto be inactive when they are not part of the current priority grouping, 279*6ba597c5SAnurag S. Maskeywhile on the other we want to watch out for new WLANs appearing in 280*6ba597c5SAnurag S. Maskeyscan data if the WiFi link is of a higher priority than the currently-selected 281*6ba597c5SAnurag S. Maskeygroup. The reason we watch out for these is they represent the potential 282*6ba597c5SAnurag S. Maskeyto change priority grouping to a more preferred group. To accommodate this, 283*6ba597c5SAnurag S. MaskeyWiFi links of the same or lower (more preferred) priority group will always 284*6ba597c5SAnurag S. Maskeybe trying to connect (and thus be offline* if they cannot). 285*6ba597c5SAnurag S. Maskey 286*6ba597c5SAnurag S. MaskeyIt might appear unnecessary to have a separate state value/machine for 287*6ba597c5SAnurag S. Maskeyauxiliary state - why can't we simply add the auxiliary state machine to the 288*6ba597c5SAnurag S. Maskeyglobal object state machine? Part of the answer is that there are times we 289*6ba597c5SAnurag S. Maskeyneed to run through the same configuration state machine when the global 290*6ba597c5SAnurag S. Maskeyobject state is different - in paticular either offline* or online. Consider 291*6ba597c5SAnurag S. MaskeyWiFi - we want to do periodic scans to find a "better" WLAN - we can easily 292*6ba597c5SAnurag S. Maskeydo this by running back through the link state machine of auxiliary 293*6ba597c5SAnurag S. Maskeystates, but we want to stay online while we do it, since we are still 294*6ba597c5SAnurag S. Maskeyconnected (if the WLAN disconnects of course we go to LINK_DOWN and offline). 295*6ba597c5SAnurag S. Maskey 296*6ba597c5SAnurag S. MaskeyAnother reason we wish to separate the more general states (offline, online 297*6ba597c5SAnurag S. Maskeyetc) from the more specific ones (WIFI_NEED_SELECTION etc) is to ensure 298*6ba597c5SAnurag S. Maskeythat the representation of configuration objects closely matches the way 299*6ba597c5SAnurag S. MaskeySMF works. 300*6ba597c5SAnurag S. Maskey 301*6ba597c5SAnurag S. MaskeyFor an NCU physical link, the following link-specific auxiliary states are 302*6ba597c5SAnurag S. Maskeyused: 303*6ba597c5SAnurag S. Maskey 304*6ba597c5SAnurag S. MaskeyAuxiliary state Description 305*6ba597c5SAnurag S. Maskey=============== =========== 306*6ba597c5SAnurag S. Maskey 307*6ba597c5SAnurag S. MaskeyLINK_WIFI_SCANNING Scan in progress 308*6ba597c5SAnurag S. MaskeyLINK_WIFI_NEED_SELECTION Need user to specify WLAN 309*6ba597c5SAnurag S. MaskeyLINK_WIFI_NEED_KEY Need user to specify a WLAN key for selection 310*6ba597c5SAnurag S. MaskeyLINK_WIFI_CONNECTING Connecting to current selection 311*6ba597c5SAnurag S. Maskey 312*6ba597c5SAnurag S. MaskeyA WiFI link differs from a wired one in that it always has the 313*6ba597c5SAnurag S. Maskeypotential to be available - it just depends if visited WLANs are in range. 314*6ba597c5SAnurag S. MaskeySo such links - if they are higher in the priority grouping than the 315*6ba597c5SAnurag S. Maskeycurrently-active priority group - should always be able to scan, as they 316*6ba597c5SAnurag S. Maskeyare always "trying" to be activated. 317*6ba597c5SAnurag S. Maskey 318*6ba597c5SAnurag S. MaskeyWired links that do not support DL_NOTE_LINK_UP/DOWN are problematic, 319*6ba597c5SAnurag S. Maskeysince we have to simply assume a cable is plugged in. If an IP NCU 320*6ba597c5SAnurag S. Maskeyis activated above such a link, and that NCU uses DHCP, a timeout 321*6ba597c5SAnurag S. Maskeywill be triggered eventually (user-configurable via the nwamd/ncu_wait_time 322*6ba597c5SAnurag S. MaskeySMF property of the network/physical:nwam instance) which will cause 323*6ba597c5SAnurag S. Maskeyus to give up on the link. 324*6ba597c5SAnurag S. Maskey 325*6ba597c5SAnurag S. MaskeyFor an IP interface NCU, the following auxiliary states are suggested. 326*6ba597c5SAnurag S. Maskey 327*6ba597c5SAnurag S. MaskeyAuxiliary state Description 328*6ba597c5SAnurag S. Maskey=============== =========== 329*6ba597c5SAnurag S. Maskey 330*6ba597c5SAnurag S. MaskeyNWAM_AUX_STATE_IF_WAITING_FOR_ADDR Waiting for an address to be assigned 331*6ba597c5SAnurag S. MaskeyNWAM_AUX_STATE_IF_DHCP_TIMED_OUT DHCP timed out on interface 332*6ba597c5SAnurag S. Maskey 333*6ba597c5SAnurag S. MaskeyA link can have multiple logical interfaces plumbed on it consisting 334*6ba597c5SAnurag S. Maskeyof a mix of static and DHCP-acquired addresses. This means that 335*6ba597c5SAnurag S. Maskeywe need to decide how to aggregate the state of these logical 336*6ba597c5SAnurag S. Maskeyinterfaces into the NCU state. The concept of "up" we use here 337*6ba597c5SAnurag S. Maskeydoes not correspond to IFF_UP or IFF_RUNNING, but rather 338*6ba597c5SAnurag S. Maskeywhen we get (via getting RTM_NEWADDR events with non-zero 339*6ba597c5SAnurag S. Maskeyaddresses) at least one address assigned to the link. 340*6ba597c5SAnurag S. Maskey 341*6ba597c5SAnurag S. MaskeyWe use this concept of up as it represents the potential for 342*6ba597c5SAnurag S. Maskeynetwork communication - e.g. after assigning a static 343*6ba597c5SAnurag S. Maskeyaddress, if the location specifies nameserver etc, it 344*6ba597c5SAnurag S. Maskeyis possible to communicate over the network. One important 345*6ba597c5SAnurag S. Maskeyedge case here is that when DHCP information comes 346*6ba597c5SAnurag S. Maskeyin, we need to reassess location activation conditions and 347*6ba597c5SAnurag S. Maskeypossibly change or reapply the current location. The problem 348*6ba597c5SAnurag S. Maskeyis that if we have a static/DHCP mix, and if we rely on 349*6ba597c5SAnurag S. Maskeythe IP interface's notion of "up" to trigger location activation, 350*6ba597c5SAnurag S. Maskeywe will likely first apply the location when the static address 351*6ba597c5SAnurag S. Maskeyhas been assigned and before the DHCP information has 352*6ba597c5SAnurag S. Maskeybeen returned (which may include nameserver info). So 353*6ba597c5SAnurag S. Maskeythe solution is that on getting an RTM_NEWADDR, we 354*6ba597c5SAnurag S. Maskeycheck if the (logical) interface associated is DHCP, and 355*6ba597c5SAnurag S. Maskeyeven if the interface NCU is already up, we reassess 356*6ba597c5SAnurag S. Maskeylocation activation. This will lead to a reapplication of 357*6ba597c5SAnurag S. Maskeythe current location or possibly a location switch. 358*6ba597c5SAnurag S. Maskey 359*6ba597c5SAnurag S. MaskeyIn order to move through the various states, a generic 360*6ba597c5SAnurag S. MaskeyAPI is supplied 361*6ba597c5SAnurag S. Maskey 362*6ba597c5SAnurag S. Maskeynwam_error_t 363*6ba597c5SAnurag S. Maskeynwamd_object_set_state(nwamd_object_t obj, nwamd_state_t state, 364*6ba597c5SAnurag S. Maskey nwamd_aux_state_t aux_state); 365*6ba597c5SAnurag S. Maskey 366*6ba597c5SAnurag S. MaskeyThis function creates an OBJECT_STATE event containing 367*6ba597c5SAnurag S. Maskeythe new state/aux_state and enqueues it in the event 368*6ba597c5SAnurag S. Maskeyqueue. Each object registers its own handler for this 369*6ba597c5SAnurag S. Maskeyevent, and in response to the current state/aux state and 370*6ba597c5SAnurag S. Maskeydesired aux state it responds appropriately in the event 371*6ba597c5SAnurag S. Maskeyhandling thread, spawning other threads to carry out 372*6ba597c5SAnurag S. Maskeyactions as appropriate. The object state event is 373*6ba597c5SAnurag S. Maskeythen sent to any registered listeners. 374*6ba597c5SAnurag S. Maskey 375*6ba597c5SAnurag S. MaskeySo for NCUs, we define a handle_object_state() function 376*6ba597c5SAnurag S. Maskeyto run the state machine for the NCU object. 377*6ba597c5SAnurag S. Maskey 378*6ba597c5SAnurag S. MaskeyLink state and NCP policy 379*6ba597c5SAnurag S. Maskey========================= 380*6ba597c5SAnurag S. Maskey 381*6ba597c5SAnurag S. MaskeyNCPs can be either: 382*6ba597c5SAnurag S. Maskey 383*6ba597c5SAnurag S. Maskeyo prioritized: where the constituent link NCUs specify priority group 384*6ba597c5SAnurag S. Maskey numbers (where lower are more favoured) and grouping types. These 385*6ba597c5SAnurag S. Maskey are used to allow link NCUs to be either grouped separately (exclusive) 386*6ba597c5SAnurag S. Maskey or together (shared or all). 387*6ba597c5SAnurag S. Maskeyo manual: their activation is governed by the value of their enabled 388*6ba597c5SAnurag S. Maskey property. 389*6ba597c5SAnurag S. Maskeyo a combination of the above. 390*6ba597c5SAnurag S. Maskey 391*6ba597c5SAnurag S. MaskeyIP interface NCUs interit their activation from the links below them, 392*6ba597c5SAnurag S. Maskeyso an IP interface NCU will be active if its underlying link is (assuming 393*6ba597c5SAnurag S. Maskeyit hasn't been disabled). 394*6ba597c5SAnurag S. Maskey 395*6ba597c5SAnurag S. MaskeyAt startup, and at regular intervals (often triggered by NWAM 396*6ba597c5SAnurag S. Maskeyevents), the NCP policy needs to be reassessed. There 397*6ba597c5SAnurag S. Maskeyare a number of causes for NCP policy to be reassessed - 398*6ba597c5SAnurag S. Maskey 399*6ba597c5SAnurag S. Maskeyo a periodic check of link state that occurs every N seconds 400*6ba597c5SAnurag S. Maskeyo a link goes from offline(*) to online (cable plug/wifi connect) 401*6ba597c5SAnurag S. Maskeyo a link goes from online to offline (cable unplug/wifi disconnect). 402*6ba597c5SAnurag S. Maskey 403*6ba597c5SAnurag S. MaskeyAny of these should cause the link selecton algorithm to rerun. 404*6ba597c5SAnurag S. Maskey 405*6ba597c5SAnurag S. MaskeyThe link selection algorithm works as follows: 406*6ba597c5SAnurag S. Maskey 407*6ba597c5SAnurag S. MaskeyStarting from the lowest priority grouping value, assess all links 408*6ba597c5SAnurag S. Maskeyin that priority group. 409*6ba597c5SAnurag S. Maskey 410*6ba597c5SAnurag S. MaskeyThe current priority-group is considered failed if: 411*6ba597c5SAnurag S. Maskey 412*6ba597c5SAnurag S. Maskeyo "exclusive" NCUs exist and none are offline*/online, 413*6ba597c5SAnurag S. Maskeyo "shared" NCUs exist and none are offline*/online, 414*6ba597c5SAnurag S. Maskeyo "all" NCUs exist and all are not offline*/online, 415*6ba597c5SAnurag S. Maskeyo no NCUs are offline*/online. 416*6ba597c5SAnurag S. Maskey 417*6ba597c5SAnurag S. MaskeyWe do not invalidate a link that is offline* since its configuration 418*6ba597c5SAnurag S. Maskeyis in progress. This has the unfortunate side-effect that 419*6ba597c5SAnurag S. Maskeywired links that do not do DL_NOTE_LINK_UP/DOWN will never 420*6ba597c5SAnurag S. Maskeyfail. If such links wish to be skipped, their priority group value 421*6ba597c5SAnurag S. Maskeyshould be increased (prioritizing wireless links). 422*6ba597c5SAnurag S. Maskey 423*6ba597c5SAnurag S. MaskeyOne a priority group has been selected, all links in groups above 424*6ba597c5SAnurag S. Maskey_and_ below it need to be moved offline. 425*6ba597c5SAnurag S. Maskey 426*6ba597c5SAnurag S. MaskeyLocation Activation 427*6ba597c5SAnurag S. Maskey=================== 428*6ba597c5SAnurag S. MaskeyA basic set of system-supplied locations are supplied - NoNet and 429*6ba597c5SAnurag S. MaskeyAutomatic. nwamd will apply the NoNet location until such a time 430*6ba597c5SAnurag S. Maskeyas an interface NCU is online, at which point it will switch 431*6ba597c5SAnurag S. Maskeyto the Automatic location. If a user-supplied location is supplied, 432*6ba597c5SAnurag S. Maskeyand it is either manually enabled or its conditions are satisfied, it 433*6ba597c5SAnurag S. Maskeywill be preferred and activated instead. Only one location can be 434*6ba597c5SAnurag S. Maskeyactive at once since each location has its own specification of nameservices 435*6ba597c5SAnurag S. Maskeyetc. 436*6ba597c5SAnurag S. Maskey 437*6ba597c5SAnurag S. MaskeyENM Activation 438*6ba597c5SAnurag S. Maskey============== 439*6ba597c5SAnurag S. MaskeyENMs are either manual or conditional in activation and will be 440*6ba597c5SAnurag S. Maskeyactivated if they are enabled (manual) or if the conditions 441*6ba597c5SAnurag S. Maskeyare met (conditional). Multiple ENMs can be active at once. 442