1*11767SAnurag.Maskey@Sun.COMCDDL HEADER START 2*11767SAnurag.Maskey@Sun.COM 3*11767SAnurag.Maskey@Sun.COMThe contents of this file are subject to the terms of the 4*11767SAnurag.Maskey@Sun.COMCommon Development and Distribution License (the "License"). 5*11767SAnurag.Maskey@Sun.COMYou may not use this file except in compliance with the License. 6*11767SAnurag.Maskey@Sun.COM 7*11767SAnurag.Maskey@Sun.COMYou can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 8*11767SAnurag.Maskey@Sun.COMor http://www.opensolaris.org/os/licensing. 9*11767SAnurag.Maskey@Sun.COMSee the License for the specific language governing permissions 10*11767SAnurag.Maskey@Sun.COMand limitations under the License. 11*11767SAnurag.Maskey@Sun.COM 12*11767SAnurag.Maskey@Sun.COMWhen distributing Covered Code, include this CDDL HEADER in each 13*11767SAnurag.Maskey@Sun.COMfile and include the License file at usr/src/OPENSOLARIS.LICENSE. 14*11767SAnurag.Maskey@Sun.COMIf applicable, add the following below this CDDL HEADER, with the 15*11767SAnurag.Maskey@Sun.COMfields enclosed by brackets "[]" replaced with your own identifying 16*11767SAnurag.Maskey@Sun.COMinformation: Portions Copyright [yyyy] [name of copyright owner] 17*11767SAnurag.Maskey@Sun.COM 18*11767SAnurag.Maskey@Sun.COMCDDL HEADER END 19*11767SAnurag.Maskey@Sun.COM 20*11767SAnurag.Maskey@Sun.COMCopyright 2010 Sun Microsystems, Inc. All rights reserved. 21*11767SAnurag.Maskey@Sun.COMUse is subject to license terms. 22*11767SAnurag.Maskey@Sun.COM 23*11767SAnurag.Maskey@Sun.COMImplementation Overview for the NetWork AutoMagic daemon 24*11767SAnurag.Maskey@Sun.COMJohn Beck, Renee Danson, Michael Hunter, Alan Maguire, Kacheong Poon, 25*11767SAnurag.Maskey@Sun.COMGarima Tripathi, Jan Xie, Anurag Maskey 26*11767SAnurag.Maskey@Sun.COM[Structure and some content shamelessly stolen from Peter Memishian's 27*11767SAnurag.Maskey@Sun.COMdhcpagent architecture overview.] 28*11767SAnurag.Maskey@Sun.COM 29*11767SAnurag.Maskey@Sun.COMINTRODUCTION 30*11767SAnurag.Maskey@Sun.COM============ 31*11767SAnurag.Maskey@Sun.COM 32*11767SAnurag.Maskey@Sun.COMDetails about the NWAM requirements, architecture, and design are 33*11767SAnurag.Maskey@Sun.COMavailable via the NWAM opensolaris project at 34*11767SAnurag.Maskey@Sun.COMhttp://opensolaris.org/os/project/nwam. The point of this document is 35*11767SAnurag.Maskey@Sun.COMto place details relevant to somebody attempting to understand the 36*11767SAnurag.Maskey@Sun.COMimplementation close to the source code. 37*11767SAnurag.Maskey@Sun.COM 38*11767SAnurag.Maskey@Sun.COMTHE BASICS 39*11767SAnurag.Maskey@Sun.COM========== 40*11767SAnurag.Maskey@Sun.COM 41*11767SAnurag.Maskey@Sun.COMSOURCE FILE ORGANIZATION 42*11767SAnurag.Maskey@Sun.COM======================= 43*11767SAnurag.Maskey@Sun.COMevent sources: 44*11767SAnurag.Maskey@Sun.COM dlpi_events.c 45*11767SAnurag.Maskey@Sun.COM routing_events.c 46*11767SAnurag.Maskey@Sun.COM sysevent_events.c 47*11767SAnurag.Maskey@Sun.COM 48*11767SAnurag.Maskey@Sun.COMobject-specific event handlers: 49*11767SAnurag.Maskey@Sun.COM enm.c 50*11767SAnurag.Maskey@Sun.COM known_wlans.c 51*11767SAnurag.Maskey@Sun.COM loc.c 52*11767SAnurag.Maskey@Sun.COM ncp.c 53*11767SAnurag.Maskey@Sun.COM ncu_ip.c 54*11767SAnurag.Maskey@Sun.COM ncu_phys.c 55*11767SAnurag.Maskey@Sun.COM 56*11767SAnurag.Maskey@Sun.COMlegacy config upgrade 57*11767SAnurag.Maskey@Sun.COM llp.c 58*11767SAnurag.Maskey@Sun.COM 59*11767SAnurag.Maskey@Sun.COMgeneric code: 60*11767SAnurag.Maskey@Sun.COM objects.c 61*11767SAnurag.Maskey@Sun.COM events.c 62*11767SAnurag.Maskey@Sun.COM conditions.c 63*11767SAnurag.Maskey@Sun.COM logging.c 64*11767SAnurag.Maskey@Sun.COM util.c 65*11767SAnurag.Maskey@Sun.COM 66*11767SAnurag.Maskey@Sun.COMnwam door requests: 67*11767SAnurag.Maskey@Sun.COM door_if.c 68*11767SAnurag.Maskey@Sun.COM 69*11767SAnurag.Maskey@Sun.COMentry point: 70*11767SAnurag.Maskey@Sun.COM main.c 71*11767SAnurag.Maskey@Sun.COM 72*11767SAnurag.Maskey@Sun.COMOVERVIEW 73*11767SAnurag.Maskey@Sun.COM======== 74*11767SAnurag.Maskey@Sun.COM 75*11767SAnurag.Maskey@Sun.COMHere we discuss the essential objects and subtle aspects of the NWAM 76*11767SAnurag.Maskey@Sun.COMdaemon implementation. Note that there is of course much more that is 77*11767SAnurag.Maskey@Sun.COMnot discussed here, but after this overview you should be able to fend 78*11767SAnurag.Maskey@Sun.COMfor yourself in the source code. 79*11767SAnurag.Maskey@Sun.COM 80*11767SAnurag.Maskey@Sun.COMEvents and Objects 81*11767SAnurag.Maskey@Sun.COM================== 82*11767SAnurag.Maskey@Sun.COM 83*11767SAnurag.Maskey@Sun.COMEvents come to NWAM from a variety of different sources asyncronously. 84*11767SAnurag.Maskey@Sun.COM 85*11767SAnurag.Maskey@Sun.COMo routing socket 86*11767SAnurag.Maskey@Sun.COMo dlpi 87*11767SAnurag.Maskey@Sun.COMo sysevents 88*11767SAnurag.Maskey@Sun.COMo doors 89*11767SAnurag.Maskey@Sun.COM 90*11767SAnurag.Maskey@Sun.COMRouting sockets and dlpi (DL_NOTE_LINK_UP|DOWN events) are handled by 91*11767SAnurag.Maskey@Sun.COMdedicated threads. Sysevents and doors are both seen as callbacks into 92*11767SAnurag.Maskey@Sun.COMthe process proper and will often post their results to the main event 93*11767SAnurag.Maskey@Sun.COMqueue. All event sources post events onto the main event queue. In 94*11767SAnurag.Maskey@Sun.COMaddition state changes of objects and door requests (requesting current 95*11767SAnurag.Maskey@Sun.COMstate or a change of state, specification of a WiFi key etc) can 96*11767SAnurag.Maskey@Sun.COMlead to additional events. We have daemon-internal events (object 97*11767SAnurag.Maskey@Sun.COMinitialization, periodic state checks) which are simply enqueued 98*11767SAnurag.Maskey@Sun.COMon the event queue, and external events which are both enqueued on 99*11767SAnurag.Maskey@Sun.COMthe event queue and sent to registered listeners (via nwam_event_send()). 100*11767SAnurag.Maskey@Sun.COM 101*11767SAnurag.Maskey@Sun.COMSo the structure of the daemon is a set of threads that drive event 102*11767SAnurag.Maskey@Sun.COMgeneration. Events are posted either directly onto the event queue 103*11767SAnurag.Maskey@Sun.COMor are delayed by posting onto the pending event queue. SIGALARMs 104*11767SAnurag.Maskey@Sun.COMare set for the event delay, and when the SIGALARM is received 105*11767SAnurag.Maskey@Sun.COMpending events that have expired are moved onto the event queue 106*11767SAnurag.Maskey@Sun.COMproper. Delayed enqueueing is useful for periodic checks. 107*11767SAnurag.Maskey@Sun.COM 108*11767SAnurag.Maskey@Sun.COMDecisions to change conditions based upon object state changes are 109*11767SAnurag.Maskey@Sun.COMdelayed until after bursts of events. This is achieved by marking a 110*11767SAnurag.Maskey@Sun.COMflag when it is deemed checking is necessary and then the next time the 111*11767SAnurag.Maskey@Sun.COMqueue is empty performing those checks. A typical event profile will 112*11767SAnurag.Maskey@Sun.COMbe one event (e.g. a link down) causing a flurry of other events (e.g. 113*11767SAnurag.Maskey@Sun.COMrelated interface down). By waiting until all the consequences of the 114*11767SAnurag.Maskey@Sun.COMinitial event have been carried out to make higher level decisions we 115*11767SAnurag.Maskey@Sun.COMimplicitly debounce those higher level decisions. 116*11767SAnurag.Maskey@Sun.COM 117*11767SAnurag.Maskey@Sun.COMAt the moment queue quiet actually means that the queue has been quiet 118*11767SAnurag.Maskey@Sun.COMfor some short period of time (.1s). Typically the flurry of events we 119*11767SAnurag.Maskey@Sun.COMwant to work through are internally generated and are back to back in 120*11767SAnurag.Maskey@Sun.COMthe queue. We wait a bit longer in case there are reprucussions from 121*11767SAnurag.Maskey@Sun.COMwhat we do that cause external events to be posted on us. We are not 122*11767SAnurag.Maskey@Sun.COMinterested in waiting for longer term things to happen but merely to 123*11767SAnurag.Maskey@Sun.COMcatch immediate changes. 124*11767SAnurag.Maskey@Sun.COM 125*11767SAnurag.Maskey@Sun.COMWhen running, the daemon will consist of a number of threads: 126*11767SAnurag.Maskey@Sun.COM 127*11767SAnurag.Maskey@Sun.COMo the event handling thread: a thread blocking until events appear on the 128*11767SAnurag.Maskey@Sun.COM event queue, processing each event in order. Events that require 129*11767SAnurag.Maskey@Sun.COM time-consuming processing are spawned in worker threads (e.g. WiFi 130*11767SAnurag.Maskey@Sun.COM connect, DHCP requests etc). 131*11767SAnurag.Maskey@Sun.COMo door request threads: the door infrastructure manages server threads 132*11767SAnurag.Maskey@Sun.COM which process synchronous NWAM client requests (e.g. get state of an 133*11767SAnurag.Maskey@Sun.COM object, connect to a specific WLAN, initiate a scan on a link etc). 134*11767SAnurag.Maskey@Sun.COMo various wifi/IP threads: threads which do asynchronous work such as 135*11767SAnurag.Maskey@Sun.COM DHCP requests, WLAN scans etc that cannot hold up event processing in 136*11767SAnurag.Maskey@Sun.COM the main event handling thread. 137*11767SAnurag.Maskey@Sun.COMo routing socket threads: process routing socket messages of interest 138*11767SAnurag.Maskey@Sun.COM (address additons/deletions) and package them as NWAM messages. 139*11767SAnurag.Maskey@Sun.COMo dlpi threads: used to monitor for DL_NOTE_LINK messages on links 140*11767SAnurag.Maskey@Sun.COM 141*11767SAnurag.Maskey@Sun.COMThe daemon is structured around a set of objects representing NCPs[1], 142*11767SAnurag.Maskey@Sun.COMNCUs[2], ENMs[3] and known WLANs and a set of state machines which 143*11767SAnurag.Maskey@Sun.COMconsume events which act on those objects. Object lists are maintained 144*11767SAnurag.Maskey@Sun.COMfor each object type, and these contain both a libnwam handle (to allow 145*11767SAnurag.Maskey@Sun.COMreading the object directly) and an optional object data pointer which 146*11767SAnurag.Maskey@Sun.COMcan point to state information used to configure the object. 147*11767SAnurag.Maskey@Sun.COM 148*11767SAnurag.Maskey@Sun.COMEvents can be associated with specific objects (e.g. link up), or associated 149*11767SAnurag.Maskey@Sun.COMwith no object in particular (e.g. shutdown). 150*11767SAnurag.Maskey@Sun.COM 151*11767SAnurag.Maskey@Sun.COMEach object type registers a set of event handler functions with the event 152*11767SAnurag.Maskey@Sun.COMframework such that when an event occurs, the appropriate handler for the 153*11767SAnurag.Maskey@Sun.COMobject type is used. The event handlers are usually called 154*11767SAnurag.Maskey@Sun.COMnwamd_handle_*_event(). 155*11767SAnurag.Maskey@Sun.COM 156*11767SAnurag.Maskey@Sun.COM[1] NCP Network Configuration Profile; the set of link- and IP-layer 157*11767SAnurag.Maskey@Sun.COMconfiguration units which collectively specify how a system should be 158*11767SAnurag.Maskey@Sun.COMconnected to the network 159*11767SAnurag.Maskey@Sun.COM 160*11767SAnurag.Maskey@Sun.COM[2] NCU Network Configuration Unit; the individual components of an NCP 161*11767SAnurag.Maskey@Sun.COM 162*11767SAnurag.Maskey@Sun.COM[3] ENM External Network Modifiers; user executable scripts often used 163*11767SAnurag.Maskey@Sun.COMto configure a VPN 164*11767SAnurag.Maskey@Sun.COM 165*11767SAnurag.Maskey@Sun.COMDoors and External Events 166*11767SAnurag.Maskey@Sun.COM========================= 167*11767SAnurag.Maskey@Sun.COM 168*11767SAnurag.Maskey@Sun.COMThe command interface to nwamd is thread a door at NWAM_DOOR 169*11767SAnurag.Maskey@Sun.COM(/etc/svc/volatile/nwam/nwam_door). This door allows external program to send 170*11767SAnurag.Maskey@Sun.COMmessages to nwamd. The way doors work is to provide a mechanism for 171*11767SAnurag.Maskey@Sun.COManother process to execute code in your process space. This looks like 172*11767SAnurag.Maskey@Sun.COMa CSPish send/receive/reply in that the receiving process provide a 173*11767SAnurag.Maskey@Sun.COMsyncronization point (via door_create(3C)), the calling process uses 174*11767SAnurag.Maskey@Sun.COMthat syncronization point to rendezvous with and provide arguments (via 175*11767SAnurag.Maskey@Sun.COMdoor_call(3C), and then the receive process reply (via 176*11767SAnurag.Maskey@Sun.COMdoor_return(3C))) passing back data as required. The OS makes it such 177*11767SAnurag.Maskey@Sun.COMthat the memory used to pass data via door_call(3C) is mapped into the 178*11767SAnurag.Maskey@Sun.COMreceiving process which can write back into it and then transparently 179*11767SAnurag.Maskey@Sun.COMhave it mapped back to the calling process. 180*11767SAnurag.Maskey@Sun.COM 181*11767SAnurag.Maskey@Sun.COMAs well as handling internal events of interest, the daemon also needs 182*11767SAnurag.Maskey@Sun.COMto send events of interest (link up/down, WLAN scan/connect results etc) 183*11767SAnurag.Maskey@Sun.COMto (possibly) multiple NWAM client listeners. This is done via 184*11767SAnurag.Maskey@Sun.COMSystem V message queues. On registering for events via a libnwam door 185*11767SAnurag.Maskey@Sun.COMrequest into the daemon (nwam_events_register()), a per-client 186*11767SAnurag.Maskey@Sun.COM(identified by pid) message queue file is created. The 187*11767SAnurag.Maskey@Sun.COMdaemon sends messages to all listeners by examining the list of 188*11767SAnurag.Maskey@Sun.COMmessage queue files (allowing registration to be robust across 189*11767SAnurag.Maskey@Sun.COMdaemon restarts) and sending events to each listener. This is done 190*11767SAnurag.Maskey@Sun.COMvia the libnwam function nwam_event_send() which hides the IPC 191*11767SAnurag.Maskey@Sun.COMmechanism from the daemon. 192*11767SAnurag.Maskey@Sun.COM 193*11767SAnurag.Maskey@Sun.COMObjects 194*11767SAnurag.Maskey@Sun.COM======= 195*11767SAnurag.Maskey@Sun.COMFour object lists are maintained within the daemon - one each for 196*11767SAnurag.Maskey@Sun.COMthe configuration objects libnwam manages. i.e.: 197*11767SAnurag.Maskey@Sun.COM 198*11767SAnurag.Maskey@Sun.COMo ENMs 199*11767SAnurag.Maskey@Sun.COMo locations 200*11767SAnurag.Maskey@Sun.COMo known WLANs 201*11767SAnurag.Maskey@Sun.COMo NCUs of the current active NCP 202*11767SAnurag.Maskey@Sun.COM 203*11767SAnurag.Maskey@Sun.COMObjects have an associated libnwam handle and an optional data 204*11767SAnurag.Maskey@Sun.COMfield (which is used for NCUs only). 205*11767SAnurag.Maskey@Sun.COM 206*11767SAnurag.Maskey@Sun.COMLocking is straightforward - nwamd_object_init() will initialize 207*11767SAnurag.Maskey@Sun.COMan object of a particular type in the appropriate object list, 208*11767SAnurag.Maskey@Sun.COMreturning it with the object lock held. When it is no longer needed, 209*11767SAnurag.Maskey@Sun.COMnwamd_object_unlock() should be called on the object. 210*11767SAnurag.Maskey@Sun.COM 211*11767SAnurag.Maskey@Sun.COMTo retrieve an existing object, nwamd_object_find() should be 212*11767SAnurag.Maskey@Sun.COMcalled - again this returns the object in a locked state. 213*11767SAnurag.Maskey@Sun.COM 214*11767SAnurag.Maskey@Sun.COMnwamd_object_lock() is deliberately not exposed outside of objects.c, 215*11767SAnurag.Maskey@Sun.COMsince object locking is implicit in the above creation/retrieval 216*11767SAnurag.Maskey@Sun.COMfunctions. 217*11767SAnurag.Maskey@Sun.COM 218*11767SAnurag.Maskey@Sun.COMAn object is removed from the object list (with handle destroyed) 219*11767SAnurag.Maskey@Sun.COMvia nwamd_object_fini() - the object data (if any) is returned 220*11767SAnurag.Maskey@Sun.COMfrom this call to allow deallocation. 221*11767SAnurag.Maskey@Sun.COM 222*11767SAnurag.Maskey@Sun.COMObject state 223*11767SAnurag.Maskey@Sun.COM============ 224*11767SAnurag.Maskey@Sun.COMnwamd deals with 3 broad types of object that need to maintain 225*11767SAnurag.Maskey@Sun.COMinternal state: NCUs, ENMs and locations (known WLANs are configuration 226*11767SAnurag.Maskey@Sun.COMobjects but don't have a state beyond simply being present). 227*11767SAnurag.Maskey@Sun.COMNWAM objects all share a basic set of states: 228*11767SAnurag.Maskey@Sun.COM 229*11767SAnurag.Maskey@Sun.COMState Description 230*11767SAnurag.Maskey@Sun.COM===== =========== 231*11767SAnurag.Maskey@Sun.COMuninitialized object representation not present on system or in nwamd 232*11767SAnurag.Maskey@Sun.COMinitialized object representation present in system and in nwamd 233*11767SAnurag.Maskey@Sun.COMdisabled disabled manually 234*11767SAnurag.Maskey@Sun.COMoffline external conditions are not satisfied 235*11767SAnurag.Maskey@Sun.COMoffline* external conditions are satisfied, trying to move online 236*11767SAnurag.Maskey@Sun.COMonline* external conditions no longer satisfied, trying to move offline 237*11767SAnurag.Maskey@Sun.COMonline conditions satisfied and configured 238*11767SAnurag.Maskey@Sun.COMmaintenance error occurred in applying configuration 239*11767SAnurag.Maskey@Sun.COM 240*11767SAnurag.Maskey@Sun.COMThese deliberately mimic SMF states. 241*11767SAnurag.Maskey@Sun.COM 242*11767SAnurag.Maskey@Sun.COMThe states of interest are offline, offline* and online. 243*11767SAnurag.Maskey@Sun.COM 244*11767SAnurag.Maskey@Sun.COMAn object (link/interface NCU, ENM or location) should only move online 245*11767SAnurag.Maskey@Sun.COMwhen its conditions are satisfied _and_ its configuration has been successfully 246*11767SAnurag.Maskey@Sun.COMapplied. This occurs when an ENM method has run or a link is up, or an 247*11767SAnurag.Maskey@Sun.COMinterface has at least one address assigned. 248*11767SAnurag.Maskey@Sun.COM 249*11767SAnurag.Maskey@Sun.COMTo understand the distinction between offline and offline*, consider the case 250*11767SAnurag.Maskey@Sun.COMwhere a link is of prioritized activation, and either is a lower priority 251*11767SAnurag.Maskey@Sun.COMgroup - and hence inactive (due to cable being unplugged or inability to 252*11767SAnurag.Maskey@Sun.COMconnect to wifi) - or a higher priority group - and hence active. In general, 253*11767SAnurag.Maskey@Sun.COMwe want to distinguish between two cases: 254*11767SAnurag.Maskey@Sun.COM 255*11767SAnurag.Maskey@Sun.COM1) when we are actively configuring the link with a view to moving online 256*11767SAnurag.Maskey@Sun.COM(offline*), as would be the case when the link's priority group is 257*11767SAnurag.Maskey@Sun.COMactive. 258*11767SAnurag.Maskey@Sun.COM2) when external policy-based conditions prevent a link from being active. 259*11767SAnurag.Maskey@Sun.COMoffline should be used for such cases. Links in priority groups above and 260*11767SAnurag.Maskey@Sun.COMbelow the currently-active group will be offline, since policy precludes them 261*11767SAnurag.Maskey@Sun.COMfrom activating (as less-prioritized links). 262*11767SAnurag.Maskey@Sun.COM 263*11767SAnurag.Maskey@Sun.COMSo we see that offline and offline* can thus be used to distinguish between 264*11767SAnurag.Maskey@Sun.COMcases that have the potentiality to move online (offline*) from a policy 265*11767SAnurag.Maskey@Sun.COMperspective - i.e. conditions on the location allow it, or link prioritization 266*11767SAnurag.Maskey@Sun.COMallows it - and cases where external conditions dictate that it should not 267*11767SAnurag.Maskey@Sun.COM(offline). 268*11767SAnurag.Maskey@Sun.COM 269*11767SAnurag.Maskey@Sun.COMOnce an object reaches offline*, its configuration processes should kick in. 270*11767SAnurag.Maskey@Sun.COMThis is where auxiliary state is useful, as it allows us to distinguish between 271*11767SAnurag.Maskey@Sun.COMvarious states in that configuration process. For example, a link can be 272*11767SAnurag.Maskey@Sun.COMwaiting for WLAN selection or key data, or an interface can be waiting for 273*11767SAnurag.Maskey@Sun.COMDHCP response. This auxiliary state can then also be used diagnostically by 274*11767SAnurag.Maskey@Sun.COMlibnwam consumers to determine the current status of a link, interface, ENM 275*11767SAnurag.Maskey@Sun.COMetc. 276*11767SAnurag.Maskey@Sun.COM 277*11767SAnurag.Maskey@Sun.COMWiFi links present a problem however. On the one hand, we want them 278*11767SAnurag.Maskey@Sun.COMto be inactive when they are not part of the current priority grouping, 279*11767SAnurag.Maskey@Sun.COMwhile on the other we want to watch out for new WLANs appearing in 280*11767SAnurag.Maskey@Sun.COMscan data if the WiFi link is of a higher priority than the currently-selected 281*11767SAnurag.Maskey@Sun.COMgroup. The reason we watch out for these is they represent the potential 282*11767SAnurag.Maskey@Sun.COMto change priority grouping to a more preferred group. To accommodate this, 283*11767SAnurag.Maskey@Sun.COMWiFi links of the same or lower (more preferred) priority group will always 284*11767SAnurag.Maskey@Sun.COMbe trying to connect (and thus be offline* if they cannot). 285*11767SAnurag.Maskey@Sun.COM 286*11767SAnurag.Maskey@Sun.COMIt might appear unnecessary to have a separate state value/machine for 287*11767SAnurag.Maskey@Sun.COMauxiliary state - why can't we simply add the auxiliary state machine to the 288*11767SAnurag.Maskey@Sun.COMglobal object state machine? Part of the answer is that there are times we 289*11767SAnurag.Maskey@Sun.COMneed to run through the same configuration state machine when the global 290*11767SAnurag.Maskey@Sun.COMobject state is different - in paticular either offline* or online. Consider 291*11767SAnurag.Maskey@Sun.COMWiFi - we want to do periodic scans to find a "better" WLAN - we can easily 292*11767SAnurag.Maskey@Sun.COMdo this by running back through the link state machine of auxiliary 293*11767SAnurag.Maskey@Sun.COMstates, but we want to stay online while we do it, since we are still 294*11767SAnurag.Maskey@Sun.COMconnected (if the WLAN disconnects of course we go to LINK_DOWN and offline). 295*11767SAnurag.Maskey@Sun.COM 296*11767SAnurag.Maskey@Sun.COMAnother reason we wish to separate the more general states (offline, online 297*11767SAnurag.Maskey@Sun.COMetc) from the more specific ones (WIFI_NEED_SELECTION etc) is to ensure 298*11767SAnurag.Maskey@Sun.COMthat the representation of configuration objects closely matches the way 299*11767SAnurag.Maskey@Sun.COMSMF works. 300*11767SAnurag.Maskey@Sun.COM 301*11767SAnurag.Maskey@Sun.COMFor an NCU physical link, the following link-specific auxiliary states are 302*11767SAnurag.Maskey@Sun.COMused: 303*11767SAnurag.Maskey@Sun.COM 304*11767SAnurag.Maskey@Sun.COMAuxiliary state Description 305*11767SAnurag.Maskey@Sun.COM=============== =========== 306*11767SAnurag.Maskey@Sun.COM 307*11767SAnurag.Maskey@Sun.COMLINK_WIFI_SCANNING Scan in progress 308*11767SAnurag.Maskey@Sun.COMLINK_WIFI_NEED_SELECTION Need user to specify WLAN 309*11767SAnurag.Maskey@Sun.COMLINK_WIFI_NEED_KEY Need user to specify a WLAN key for selection 310*11767SAnurag.Maskey@Sun.COMLINK_WIFI_CONNECTING Connecting to current selection 311*11767SAnurag.Maskey@Sun.COM 312*11767SAnurag.Maskey@Sun.COMA WiFI link differs from a wired one in that it always has the 313*11767SAnurag.Maskey@Sun.COMpotential to be available - it just depends if visited WLANs are in range. 314*11767SAnurag.Maskey@Sun.COMSo such links - if they are higher in the priority grouping than the 315*11767SAnurag.Maskey@Sun.COMcurrently-active priority group - should always be able to scan, as they 316*11767SAnurag.Maskey@Sun.COMare always "trying" to be activated. 317*11767SAnurag.Maskey@Sun.COM 318*11767SAnurag.Maskey@Sun.COMWired links that do not support DL_NOTE_LINK_UP/DOWN are problematic, 319*11767SAnurag.Maskey@Sun.COMsince we have to simply assume a cable is plugged in. If an IP NCU 320*11767SAnurag.Maskey@Sun.COMis activated above such a link, and that NCU uses DHCP, a timeout 321*11767SAnurag.Maskey@Sun.COMwill be triggered eventually (user-configurable via the nwamd/ncu_wait_time 322*11767SAnurag.Maskey@Sun.COMSMF property of the network/physical:nwam instance) which will cause 323*11767SAnurag.Maskey@Sun.COMus to give up on the link. 324*11767SAnurag.Maskey@Sun.COM 325*11767SAnurag.Maskey@Sun.COMFor an IP interface NCU, the following auxiliary states are suggested. 326*11767SAnurag.Maskey@Sun.COM 327*11767SAnurag.Maskey@Sun.COMAuxiliary state Description 328*11767SAnurag.Maskey@Sun.COM=============== =========== 329*11767SAnurag.Maskey@Sun.COM 330*11767SAnurag.Maskey@Sun.COMNWAM_AUX_STATE_IF_WAITING_FOR_ADDR Waiting for an address to be assigned 331*11767SAnurag.Maskey@Sun.COMNWAM_AUX_STATE_IF_DHCP_TIMED_OUT DHCP timed out on interface 332*11767SAnurag.Maskey@Sun.COM 333*11767SAnurag.Maskey@Sun.COMA link can have multiple logical interfaces plumbed on it consisting 334*11767SAnurag.Maskey@Sun.COMof a mix of static and DHCP-acquired addresses. This means that 335*11767SAnurag.Maskey@Sun.COMwe need to decide how to aggregate the state of these logical 336*11767SAnurag.Maskey@Sun.COMinterfaces into the NCU state. The concept of "up" we use here 337*11767SAnurag.Maskey@Sun.COMdoes not correspond to IFF_UP or IFF_RUNNING, but rather 338*11767SAnurag.Maskey@Sun.COMwhen we get (via getting RTM_NEWADDR events with non-zero 339*11767SAnurag.Maskey@Sun.COMaddresses) at least one address assigned to the link. 340*11767SAnurag.Maskey@Sun.COM 341*11767SAnurag.Maskey@Sun.COMWe use this concept of up as it represents the potential for 342*11767SAnurag.Maskey@Sun.COMnetwork communication - e.g. after assigning a static 343*11767SAnurag.Maskey@Sun.COMaddress, if the location specifies nameserver etc, it 344*11767SAnurag.Maskey@Sun.COMis possible to communicate over the network. One important 345*11767SAnurag.Maskey@Sun.COMedge case here is that when DHCP information comes 346*11767SAnurag.Maskey@Sun.COMin, we need to reassess location activation conditions and 347*11767SAnurag.Maskey@Sun.COMpossibly change or reapply the current location. The problem 348*11767SAnurag.Maskey@Sun.COMis that if we have a static/DHCP mix, and if we rely on 349*11767SAnurag.Maskey@Sun.COMthe IP interface's notion of "up" to trigger location activation, 350*11767SAnurag.Maskey@Sun.COMwe will likely first apply the location when the static address 351*11767SAnurag.Maskey@Sun.COMhas been assigned and before the DHCP information has 352*11767SAnurag.Maskey@Sun.COMbeen returned (which may include nameserver info). So 353*11767SAnurag.Maskey@Sun.COMthe solution is that on getting an RTM_NEWADDR, we 354*11767SAnurag.Maskey@Sun.COMcheck if the (logical) interface associated is DHCP, and 355*11767SAnurag.Maskey@Sun.COMeven if the interface NCU is already up, we reassess 356*11767SAnurag.Maskey@Sun.COMlocation activation. This will lead to a reapplication of 357*11767SAnurag.Maskey@Sun.COMthe current location or possibly a location switch. 358*11767SAnurag.Maskey@Sun.COM 359*11767SAnurag.Maskey@Sun.COMIn order to move through the various states, a generic 360*11767SAnurag.Maskey@Sun.COMAPI is supplied 361*11767SAnurag.Maskey@Sun.COM 362*11767SAnurag.Maskey@Sun.COMnwam_error_t 363*11767SAnurag.Maskey@Sun.COMnwamd_object_set_state(nwamd_object_t obj, nwamd_state_t state, 364*11767SAnurag.Maskey@Sun.COM nwamd_aux_state_t aux_state); 365*11767SAnurag.Maskey@Sun.COM 366*11767SAnurag.Maskey@Sun.COMThis function creates an OBJECT_STATE event containing 367*11767SAnurag.Maskey@Sun.COMthe new state/aux_state and enqueues it in the event 368*11767SAnurag.Maskey@Sun.COMqueue. Each object registers its own handler for this 369*11767SAnurag.Maskey@Sun.COMevent, and in response to the current state/aux state and 370*11767SAnurag.Maskey@Sun.COMdesired aux state it responds appropriately in the event 371*11767SAnurag.Maskey@Sun.COMhandling thread, spawning other threads to carry out 372*11767SAnurag.Maskey@Sun.COMactions as appropriate. The object state event is 373*11767SAnurag.Maskey@Sun.COMthen sent to any registered listeners. 374*11767SAnurag.Maskey@Sun.COM 375*11767SAnurag.Maskey@Sun.COMSo for NCUs, we define a handle_object_state() function 376*11767SAnurag.Maskey@Sun.COMto run the state machine for the NCU object. 377*11767SAnurag.Maskey@Sun.COM 378*11767SAnurag.Maskey@Sun.COMLink state and NCP policy 379*11767SAnurag.Maskey@Sun.COM========================= 380*11767SAnurag.Maskey@Sun.COM 381*11767SAnurag.Maskey@Sun.COMNCPs can be either: 382*11767SAnurag.Maskey@Sun.COM 383*11767SAnurag.Maskey@Sun.COMo prioritized: where the constituent link NCUs specify priority group 384*11767SAnurag.Maskey@Sun.COM numbers (where lower are more favoured) and grouping types. These 385*11767SAnurag.Maskey@Sun.COM are used to allow link NCUs to be either grouped separately (exclusive) 386*11767SAnurag.Maskey@Sun.COM or together (shared or all). 387*11767SAnurag.Maskey@Sun.COMo manual: their activation is governed by the value of their enabled 388*11767SAnurag.Maskey@Sun.COM property. 389*11767SAnurag.Maskey@Sun.COMo a combination of the above. 390*11767SAnurag.Maskey@Sun.COM 391*11767SAnurag.Maskey@Sun.COMIP interface NCUs interit their activation from the links below them, 392*11767SAnurag.Maskey@Sun.COMso an IP interface NCU will be active if its underlying link is (assuming 393*11767SAnurag.Maskey@Sun.COMit hasn't been disabled). 394*11767SAnurag.Maskey@Sun.COM 395*11767SAnurag.Maskey@Sun.COMAt startup, and at regular intervals (often triggered by NWAM 396*11767SAnurag.Maskey@Sun.COMevents), the NCP policy needs to be reassessed. There 397*11767SAnurag.Maskey@Sun.COMare a number of causes for NCP policy to be reassessed - 398*11767SAnurag.Maskey@Sun.COM 399*11767SAnurag.Maskey@Sun.COMo a periodic check of link state that occurs every N seconds 400*11767SAnurag.Maskey@Sun.COMo a link goes from offline(*) to online (cable plug/wifi connect) 401*11767SAnurag.Maskey@Sun.COMo a link goes from online to offline (cable unplug/wifi disconnect). 402*11767SAnurag.Maskey@Sun.COM 403*11767SAnurag.Maskey@Sun.COMAny of these should cause the link selecton algorithm to rerun. 404*11767SAnurag.Maskey@Sun.COM 405*11767SAnurag.Maskey@Sun.COMThe link selection algorithm works as follows: 406*11767SAnurag.Maskey@Sun.COM 407*11767SAnurag.Maskey@Sun.COMStarting from the lowest priority grouping value, assess all links 408*11767SAnurag.Maskey@Sun.COMin that priority group. 409*11767SAnurag.Maskey@Sun.COM 410*11767SAnurag.Maskey@Sun.COMThe current priority-group is considered failed if: 411*11767SAnurag.Maskey@Sun.COM 412*11767SAnurag.Maskey@Sun.COMo "exclusive" NCUs exist and none are offline*/online, 413*11767SAnurag.Maskey@Sun.COMo "shared" NCUs exist and none are offline*/online, 414*11767SAnurag.Maskey@Sun.COMo "all" NCUs exist and all are not offline*/online, 415*11767SAnurag.Maskey@Sun.COMo no NCUs are offline*/online. 416*11767SAnurag.Maskey@Sun.COM 417*11767SAnurag.Maskey@Sun.COMWe do not invalidate a link that is offline* since its configuration 418*11767SAnurag.Maskey@Sun.COMis in progress. This has the unfortunate side-effect that 419*11767SAnurag.Maskey@Sun.COMwired links that do not do DL_NOTE_LINK_UP/DOWN will never 420*11767SAnurag.Maskey@Sun.COMfail. If such links wish to be skipped, their priority group value 421*11767SAnurag.Maskey@Sun.COMshould be increased (prioritizing wireless links). 422*11767SAnurag.Maskey@Sun.COM 423*11767SAnurag.Maskey@Sun.COMOne a priority group has been selected, all links in groups above 424*11767SAnurag.Maskey@Sun.COM_and_ below it need to be moved offline. 425*11767SAnurag.Maskey@Sun.COM 426*11767SAnurag.Maskey@Sun.COMLocation Activation 427*11767SAnurag.Maskey@Sun.COM=================== 428*11767SAnurag.Maskey@Sun.COMA basic set of system-supplied locations are supplied - NoNet and 429*11767SAnurag.Maskey@Sun.COMAutomatic. nwamd will apply the NoNet location until such a time 430*11767SAnurag.Maskey@Sun.COMas an interface NCU is online, at which point it will switch 431*11767SAnurag.Maskey@Sun.COMto the Automatic location. If a user-supplied location is supplied, 432*11767SAnurag.Maskey@Sun.COMand it is either manually enabled or its conditions are satisfied, it 433*11767SAnurag.Maskey@Sun.COMwill be preferred and activated instead. Only one location can be 434*11767SAnurag.Maskey@Sun.COMactive at once since each location has its own specification of nameservices 435*11767SAnurag.Maskey@Sun.COMetc. 436*11767SAnurag.Maskey@Sun.COM 437*11767SAnurag.Maskey@Sun.COMENM Activation 438*11767SAnurag.Maskey@Sun.COM============== 439*11767SAnurag.Maskey@Sun.COMENMs are either manual or conditional in activation and will be 440*11767SAnurag.Maskey@Sun.COMactivated if they are enabled (manual) or if the conditions 441*11767SAnurag.Maskey@Sun.COMare met (conditional). Multiple ENMs can be active at once. 442