xref: /onnv-gate/usr/src/cmd/cmd-inet/lib/nwamd/README (revision 11767:8f30d0e611c6)
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