xref: /illumos-gate/usr/src/cmd/cmd-inet/lib/nwamd/README (revision 6ba597c5)
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