xref: /titanic_52/usr/src/cmd/cmd-inet/lib/nwamd/llp.c (revision 71ed50cf049ab14d8e0ef8d48ba17d91223e81e7)
1d71dbb73Sjbeck /*
2d71dbb73Sjbeck  * CDDL HEADER START
3d71dbb73Sjbeck  *
4d71dbb73Sjbeck  * The contents of this file are subject to the terms of the
5d71dbb73Sjbeck  * Common Development and Distribution License (the "License").
6d71dbb73Sjbeck  * You may not use this file except in compliance with the License.
7d71dbb73Sjbeck  *
8d71dbb73Sjbeck  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d71dbb73Sjbeck  * or http://www.opensolaris.org/os/licensing.
10d71dbb73Sjbeck  * See the License for the specific language governing permissions
11d71dbb73Sjbeck  * and limitations under the License.
12d71dbb73Sjbeck  *
13d71dbb73Sjbeck  * When distributing Covered Code, include this CDDL HEADER in each
14d71dbb73Sjbeck  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d71dbb73Sjbeck  * If applicable, add the following below this CDDL HEADER, with the
16d71dbb73Sjbeck  * fields enclosed by brackets "[]" replaced with your own identifying
17d71dbb73Sjbeck  * information: Portions Copyright [yyyy] [name of copyright owner]
18d71dbb73Sjbeck  *
19d71dbb73Sjbeck  * CDDL HEADER END
20d71dbb73Sjbeck  */
21d71dbb73Sjbeck 
22d71dbb73Sjbeck /*
23*71ed50cfSAnurag S. Maskey  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24d71dbb73Sjbeck  */
25d71dbb73Sjbeck 
26d71dbb73Sjbeck /*
276ba597c5SAnurag S. Maskey  * This file is here for legacy support.
28d71dbb73Sjbeck  */
29d71dbb73Sjbeck 
306ba597c5SAnurag S. Maskey #include <atomic.h>
31d71dbb73Sjbeck #include <ctype.h>
32d71dbb73Sjbeck #include <errno.h>
336ba597c5SAnurag S. Maskey #include <limits.h>
346ba597c5SAnurag S. Maskey #include <libdllink.h>
356ba597c5SAnurag S. Maskey #include <libscf.h>
366ba597c5SAnurag S. Maskey #include <stdio.h>
376ba597c5SAnurag S. Maskey #include <stdlib.h>
386ba597c5SAnurag S. Maskey #include <string.h>
396ba597c5SAnurag S. Maskey #include <strings.h>
40d71dbb73Sjbeck 
416ba597c5SAnurag S. Maskey #include <libnwam.h>
426ba597c5SAnurag S. Maskey #include "known_wlans.h"
436ba597c5SAnurag S. Maskey #include "llp.h"
446ba597c5SAnurag S. Maskey #include "ncu.h"
456ba597c5SAnurag S. Maskey #include "util.h"
46d71dbb73Sjbeck 
476ba597c5SAnurag S. Maskey /*
486ba597c5SAnurag S. Maskey  * This file formerly contained the routines that manipulate Link Layer
496ba597c5SAnurag S. Maskey  * Profiles (aka LLPs) and various support functions.  Now only code
506ba597c5SAnurag S. Maskey  * necessary for parsing the legacy /etc/nwam/llp file on upgrade is included,
516ba597c5SAnurag S. Maskey  * since this legacy configuration needs to be translated into the User NCP.
526ba597c5SAnurag S. Maskey  */
53d71dbb73Sjbeck 
546ba597c5SAnurag S. Maskey #define	OUR_OLD_DHCP_WAIT_TIME_PROP_NAME	"dhcp_wait_time"
556ba597c5SAnurag S. Maskey #define	OUR_OLD_USE_NET_SVC_PROP_NAME		"use_net_svc"
566ba597c5SAnurag S. Maskey #define	OUR_OLD_IDLE_TIME_PROP_NAME		"idle_time"
57b00044a2SJames Carlson 
58b00044a2SJames Carlson static struct qelem llp_list;
59d71dbb73Sjbeck 
60d71dbb73Sjbeck /*
61d71dbb73Sjbeck  * Global variable to hold the highest priority.  Need to use the atomic
62d71dbb73Sjbeck  * integer arithmetic functions to update it.
63d71dbb73Sjbeck  */
64b00044a2SJames Carlson static uint32_t llp_highest_pri;
65d71dbb73Sjbeck 
666ba597c5SAnurag S. Maskey /* Specifies if static address has been configured in /etc/nwam/llp */
676ba597c5SAnurag S. Maskey static boolean_t static_configured = B_FALSE;
68d71dbb73Sjbeck 
696ba597c5SAnurag S. Maskey static enum interface_type
706ba597c5SAnurag S. Maskey find_if_type(const char *name)
71b00044a2SJames Carlson {
726ba597c5SAnurag S. Maskey 	uint32_t media;
736ba597c5SAnurag S. Maskey 	enum interface_type type;
746ba597c5SAnurag S. Maskey 
756ba597c5SAnurag S. Maskey 	if (name == NULL) {
766ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "find_if_type: no ifname; "
776ba597c5SAnurag S. Maskey 		    "returning IF_UNKNOWN");
786ba597c5SAnurag S. Maskey 		return (IF_UNKNOWN);
79b00044a2SJames Carlson 	}
80b00044a2SJames Carlson 
816ba597c5SAnurag S. Maskey 	type = IF_WIRED;
826ba597c5SAnurag S. Maskey 	if (dladm_name2info(dld_handle, name, NULL, NULL, NULL, &media) !=
836ba597c5SAnurag S. Maskey 	    DLADM_STATUS_OK) {
846ba597c5SAnurag S. Maskey 		if (strncmp(name, "ip.tun", 6) == 0 ||
856ba597c5SAnurag S. Maskey 		    strncmp(name, "ip6.tun", 7) == 0 ||
866ba597c5SAnurag S. Maskey 		    strncmp(name, "ip.6to4tun", 10) == 0)
87b00044a2SJames Carlson 			/*
886ba597c5SAnurag S. Maskey 			 * We'll need to update our tunnel detection once
896ba597c5SAnurag S. Maskey 			 * the clearview/tun project is integrated; tunnel
906ba597c5SAnurag S. Maskey 			 * names won't necessarily be ip.tunN.
91b00044a2SJames Carlson 			 */
926ba597c5SAnurag S. Maskey 			type = IF_TUN;
936ba597c5SAnurag S. Maskey 	} else if (media == DL_WIFI) {
946ba597c5SAnurag S. Maskey 		type = IF_WIRELESS;
95b00044a2SJames Carlson 	}
966ba597c5SAnurag S. Maskey 
976ba597c5SAnurag S. Maskey 	return (type);
98b00044a2SJames Carlson }
99d71dbb73Sjbeck 
100b00044a2SJames Carlson static void
101b00044a2SJames Carlson llp_list_free(void)
102b00044a2SJames Carlson {
103b00044a2SJames Carlson 	llp_t *llp;
104b00044a2SJames Carlson 
105b00044a2SJames Carlson 	while (llp_list.q_forw != &llp_list) {
106b00044a2SJames Carlson 		llp = (llp_t *)llp_list.q_forw;
107b00044a2SJames Carlson 		remque(&llp->llp_links);
108b00044a2SJames Carlson 		free(llp->llp_ipv6addrstr);
109b00044a2SJames Carlson 		free(llp->llp_ipv4addrstr);
110b00044a2SJames Carlson 		free(llp);
111d71dbb73Sjbeck 	}
112d71dbb73Sjbeck }
113d71dbb73Sjbeck 
1146ba597c5SAnurag S. Maskey static void
1156ba597c5SAnurag S. Maskey initialize_llp(void)
1166ba597c5SAnurag S. Maskey {
1176ba597c5SAnurag S. Maskey 	llp_list.q_forw = llp_list.q_back = &llp_list;
1186ba597c5SAnurag S. Maskey }
1196ba597c5SAnurag S. Maskey 
1206ba597c5SAnurag S. Maskey static llp_t *
121d71dbb73Sjbeck llp_lookup(const char *link)
122d71dbb73Sjbeck {
123d71dbb73Sjbeck 	llp_t *llp;
124d71dbb73Sjbeck 
125d71dbb73Sjbeck 	if (link == NULL)
126d71dbb73Sjbeck 		return (NULL);
127d71dbb73Sjbeck 
128b00044a2SJames Carlson 	for (llp = (llp_t *)llp_list.q_forw; llp != (llp_t *)&llp_list;
129b00044a2SJames Carlson 	    llp = (llp_t *)llp->llp_links.q_forw) {
130d71dbb73Sjbeck 		if (strcmp(link, llp->llp_lname) == 0)
131d71dbb73Sjbeck 			break;
132d71dbb73Sjbeck 	}
133b00044a2SJames Carlson 	if (llp == (llp_t *)&llp_list)
134b00044a2SJames Carlson 		llp = NULL;
135d71dbb73Sjbeck 	return (llp);
136d71dbb73Sjbeck }
137d71dbb73Sjbeck 
138d71dbb73Sjbeck /*
139b00044a2SJames Carlson  * Create the named LLP with default settings.  Called only in main thread.
140d71dbb73Sjbeck  */
1416ba597c5SAnurag S. Maskey static llp_t *
142b00044a2SJames Carlson llp_add(const char *name)
143d71dbb73Sjbeck {
144b00044a2SJames Carlson 	llp_t *llp;
145d71dbb73Sjbeck 
146b00044a2SJames Carlson 	if ((llp = calloc(1, sizeof (llp_t))) == NULL) {
1476ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "llp_add: cannot allocate LLP: %m");
148b00044a2SJames Carlson 		return (NULL);
149d71dbb73Sjbeck 	}
150d71dbb73Sjbeck 
151b00044a2SJames Carlson 	if (strlcpy(llp->llp_lname, name, sizeof (llp->llp_lname)) >=
152b00044a2SJames Carlson 	    sizeof (llp->llp_lname)) {
1536ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "llp_add: linkname '%s' too long; ignoring entry",
154b00044a2SJames Carlson 		    name);
155b00044a2SJames Carlson 		free(llp);
156b00044a2SJames Carlson 		return (NULL);
157d71dbb73Sjbeck 	}
158d71dbb73Sjbeck 
159b00044a2SJames Carlson 	llp->llp_fileorder = llp->llp_pri =
160b00044a2SJames Carlson 	    atomic_add_32_nv(&llp_highest_pri, 1);
161b00044a2SJames Carlson 	llp->llp_ipv4src = IPV4SRC_DHCP;
162b00044a2SJames Carlson 	llp->llp_type = find_if_type(llp->llp_lname);
163b00044a2SJames Carlson 	llp->llp_ipv6onlink = B_TRUE;
164d71dbb73Sjbeck 
165d71dbb73Sjbeck 	/*
166d71dbb73Sjbeck 	 * should be a no-op, but for now, make sure we only
167d71dbb73Sjbeck 	 * create llps for wired and wireless interfaces.
168d71dbb73Sjbeck 	 */
169b00044a2SJames Carlson 	if (llp->llp_type != IF_WIRED && llp->llp_type != IF_WIRELESS) {
1706ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "llp_add: wrong type of interface for %s", name);
171b00044a2SJames Carlson 		free(llp);
172b00044a2SJames Carlson 		return (NULL);
173d71dbb73Sjbeck 	}
174b00044a2SJames Carlson 	insque(&llp->llp_links, llp_list.q_back);
175d71dbb73Sjbeck 
1766ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "llp_add: "
1776ba597c5SAnurag S. Maskey 	    "created llp for link %s, priority %d", llp->llp_lname,
178b00044a2SJames Carlson 	    llp->llp_pri);
179b00044a2SJames Carlson 	return (llp);
180d71dbb73Sjbeck }
181d71dbb73Sjbeck 
1826ba597c5SAnurag S. Maskey static int
1836ba597c5SAnurag S. Maskey parse_llp_config(void)
184d71dbb73Sjbeck {
185d71dbb73Sjbeck 	static const char STATICSTR[] = "static";
186d71dbb73Sjbeck 	static const char DHCP[] = "dhcp";
187d71dbb73Sjbeck 	static const char IPV6[] = "ipv6";
188d71dbb73Sjbeck 	static const char NOIPV6[] = "noipv6";
189b00044a2SJames Carlson 	static const char PRIORITY[] = "priority";
190d71dbb73Sjbeck 	FILE *fp;
191d71dbb73Sjbeck 	char line[LINE_MAX];
192b00044a2SJames Carlson 	char *cp, *lasts, *lstr, *srcstr, *addrstr;
193d71dbb73Sjbeck 	int lnum;
194b00044a2SJames Carlson 	llp_t *llp;
195b00044a2SJames Carlson 
1966ba597c5SAnurag S. Maskey 	initialize_llp();
197d71dbb73Sjbeck 
198d71dbb73Sjbeck 	fp = fopen(LLPFILE, "r+");
199d71dbb73Sjbeck 	if (fp == NULL) {
2006ba597c5SAnurag S. Maskey 		if (errno == ENOENT)
2016ba597c5SAnurag S. Maskey 			return (errno);
2026ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "parse_llp_config: "
2036ba597c5SAnurag S. Maskey 		    "open legacy LLP config file: %m");
2046ba597c5SAnurag S. Maskey 		return (-1);
205d71dbb73Sjbeck 	}
206d71dbb73Sjbeck 
207d71dbb73Sjbeck 	for (lnum = 1; fgets(line, sizeof (line), fp) != NULL; lnum++) {
208d71dbb73Sjbeck 		if (line[strlen(line) - 1] == '\n')
209d71dbb73Sjbeck 			line[strlen(line) - 1] = '\0';
210d71dbb73Sjbeck 
211d71dbb73Sjbeck 		cp = line;
212d71dbb73Sjbeck 		while (isspace(*cp))
213d71dbb73Sjbeck 			cp++;
214d71dbb73Sjbeck 
215d71dbb73Sjbeck 		if (*cp == '#' || *cp == '\0')
216d71dbb73Sjbeck 			continue;
217d71dbb73Sjbeck 
2186ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "parse_llp_config: "
2196ba597c5SAnurag S. Maskey 		    "parsing legacy LLP conf file line %d...", lnum);
220d71dbb73Sjbeck 
221d71dbb73Sjbeck 		if (((lstr = strtok_r(cp, " \t", &lasts)) == NULL) ||
222d71dbb73Sjbeck 		    ((srcstr = strtok_r(NULL, " \t", &lasts)) == NULL)) {
2236ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "parse_llp_config: line %d: "
2246ba597c5SAnurag S. Maskey 			    "not enough tokens; ignoring entry", lnum);
225d71dbb73Sjbeck 			continue;
226d71dbb73Sjbeck 		}
227b00044a2SJames Carlson 
228b00044a2SJames Carlson 		if ((llp = llp_lookup(lstr)) == NULL &&
229b00044a2SJames Carlson 		    (llp = llp_add(lstr)) == NULL) {
2306ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "parse_llp_config: line %d: "
2316ba597c5SAnurag S. Maskey 			    "cannot add entry", lnum);
232b00044a2SJames Carlson 			continue;
233b00044a2SJames Carlson 		}
234b00044a2SJames Carlson 
235d71dbb73Sjbeck 		if (strcasecmp(srcstr, STATICSTR) == 0) {
236d71dbb73Sjbeck 			if ((addrstr = strtok_r(NULL, " \t", &lasts)) == NULL ||
237d71dbb73Sjbeck 			    atoi(addrstr) == 0) { /* crude check for number */
2386ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "parse_llp_config: line %d: "
2396ba597c5SAnurag S. Maskey 				    "missing ipaddr for static config", lnum);
240b00044a2SJames Carlson 			} else if ((addrstr = strdup(addrstr)) == NULL) {
2416ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "parse_llp_config: line %d: "
2426ba597c5SAnurag S. Maskey 				    "cannot save address", lnum);
243d71dbb73Sjbeck 			} else {
244b00044a2SJames Carlson 				free(llp->llp_ipv4addrstr);
245b00044a2SJames Carlson 				llp->llp_ipv4src = IPV4SRC_STATIC;
246b00044a2SJames Carlson 				llp->llp_ipv4addrstr = addrstr;
247d71dbb73Sjbeck 			}
248d71dbb73Sjbeck 
249b00044a2SJames Carlson 		} else if (strcasecmp(srcstr, DHCP) == 0) {
250b00044a2SJames Carlson 			llp->llp_ipv4src = IPV4SRC_DHCP;
251b00044a2SJames Carlson 
252b00044a2SJames Carlson 		} else if (strcasecmp(srcstr, IPV6) == 0) {
253b00044a2SJames Carlson 			llp->llp_ipv6onlink = B_TRUE;
254b00044a2SJames Carlson 			if ((addrstr = strtok_r(NULL, " \t", &lasts)) == NULL) {
255b00044a2SJames Carlson 				(void) 0;
256b00044a2SJames Carlson 			} else if ((addrstr = strdup(addrstr)) == NULL) {
2576ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "parse_llp_config: line %d: "
2586ba597c5SAnurag S. Maskey 				    "cannot save address", lnum);
259b00044a2SJames Carlson 			} else {
260b00044a2SJames Carlson 				free(llp->llp_ipv6addrstr);
261b00044a2SJames Carlson 				llp->llp_ipv6addrstr = addrstr;
262b00044a2SJames Carlson 			}
263b00044a2SJames Carlson 
264b00044a2SJames Carlson 		} else if (strcasecmp(srcstr, NOIPV6) == 0) {
265b00044a2SJames Carlson 			llp->llp_ipv6onlink = B_FALSE;
266b00044a2SJames Carlson 
267b00044a2SJames Carlson 		} else if (strcasecmp(srcstr, PRIORITY) == 0) {
268b00044a2SJames Carlson 			if ((addrstr = strtok_r(NULL, " \t", &lasts)) == NULL) {
2696ba597c5SAnurag S. Maskey 				nlog(LOG_ERR,
2706ba597c5SAnurag S. Maskey 				    "parse_llp_config: line %d: "
2716ba597c5SAnurag S. Maskey 				    "missing priority value", lnum);
272b00044a2SJames Carlson 			} else {
273b00044a2SJames Carlson 				llp->llp_pri = atoi(addrstr);
274b00044a2SJames Carlson 			}
275b00044a2SJames Carlson 
276b00044a2SJames Carlson 		} else {
2776ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "parse_llp_config: line %d: "
2786ba597c5SAnurag S. Maskey 			    "unrecognized field '%s'", lnum, srcstr);
279b00044a2SJames Carlson 		}
280d71dbb73Sjbeck 	}
281d71dbb73Sjbeck 
282d71dbb73Sjbeck 	(void) fclose(fp);
2836ba597c5SAnurag S. Maskey 	return (0);
284d71dbb73Sjbeck }
285b00044a2SJames Carlson 
286b00044a2SJames Carlson /*
2876ba597c5SAnurag S. Maskey  * Translate legacy LLP config into the user NCP.
288b00044a2SJames Carlson  */
2896ba597c5SAnurag S. Maskey static int
2906ba597c5SAnurag S. Maskey upgrade_llp_config(void)
291b00044a2SJames Carlson {
2926ba597c5SAnurag S. Maskey 	llp_t *wp;
2936ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t user_ncp;
2946ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t phys_ncu = NULL, ip_ncu = NULL;
2956ba597c5SAnurag S. Maskey 	nwam_error_t err;
2966ba597c5SAnurag S. Maskey 	uint64_t uintval;
2976ba597c5SAnurag S. Maskey 	char *strval;
2986ba597c5SAnurag S. Maskey 	const char *prop;
299b00044a2SJames Carlson 
3006ba597c5SAnurag S. Maskey 	switch (parse_llp_config()) {
3016ba597c5SAnurag S. Maskey 	case -1:
3026ba597c5SAnurag S. Maskey 		return (0);
3036ba597c5SAnurag S. Maskey 	case ENOENT:
3046ba597c5SAnurag S. Maskey 		return (ENOENT);
3056ba597c5SAnurag S. Maskey 	default:
306b00044a2SJames Carlson 		break;
3076ba597c5SAnurag S. Maskey 	}
308*71ed50cfSAnurag S. Maskey 
309*71ed50cfSAnurag S. Maskey 	err = nwam_ncp_create(NWAM_NCP_NAME_USER, 0, &user_ncp);
310*71ed50cfSAnurag S. Maskey 	switch (err) {
311*71ed50cfSAnurag S. Maskey 	case NWAM_SUCCESS:
312*71ed50cfSAnurag S. Maskey 		break;
313*71ed50cfSAnurag S. Maskey 	case NWAM_ERROR_BIND:
314*71ed50cfSAnurag S. Maskey 	case NWAM_ERROR_INTERNAL:
3156ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "upgrade_llp_config: "
316*71ed50cfSAnurag S. Maskey 		    "could not create User NCP: %s", nwam_strerror(err));
317*71ed50cfSAnurag S. Maskey 		llp_list_free();
318*71ed50cfSAnurag S. Maskey 		return (EAGAIN);
319*71ed50cfSAnurag S. Maskey 	default:
320*71ed50cfSAnurag S. Maskey 		nlog(LOG_ERR, "upgrade_llp_config: error creating User NCP: %s",
321*71ed50cfSAnurag S. Maskey 		    nwam_strerror(err));
3226ba597c5SAnurag S. Maskey 		llp_list_free();
3236ba597c5SAnurag S. Maskey 		return (0);
3246ba597c5SAnurag S. Maskey 	}
3256ba597c5SAnurag S. Maskey 
3266ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "upgrade_llp_config: walking llp list");
3276ba597c5SAnurag S. Maskey 
3286ba597c5SAnurag S. Maskey 	for (wp = (llp_t *)llp_list.q_forw; wp != (llp_t *)&llp_list;
3296ba597c5SAnurag S. Maskey 	    wp = (llp_t *)wp->llp_links.q_forw) {
3306ba597c5SAnurag S. Maskey 
3316ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "upgrade_llp_config: "
3326ba597c5SAnurag S. Maskey 		    "upgrading llp %s", wp->llp_lname);
3336ba597c5SAnurag S. Maskey 
3346ba597c5SAnurag S. Maskey 		if (nwam_ncu_create(user_ncp, wp->llp_lname,
3356ba597c5SAnurag S. Maskey 		    NWAM_NCU_TYPE_INTERFACE, NWAM_NCU_CLASS_IP, &ip_ncu)
3366ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS ||
3376ba597c5SAnurag S. Maskey 		    nwam_ncu_create(user_ncp, wp->llp_lname, NWAM_NCU_TYPE_LINK,
3386ba597c5SAnurag S. Maskey 		    NWAM_NCU_CLASS_PHYS, &phys_ncu) != NWAM_SUCCESS) {
3396ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "upgrade_llp_config: llp %s: "
3406ba597c5SAnurag S. Maskey 			    "could not create NCUs: %s", wp->llp_lname,
3416ba597c5SAnurag S. Maskey 			    nwam_strerror(err));
342b00044a2SJames Carlson 			break;
343b00044a2SJames Carlson 		}
3446ba597c5SAnurag S. Maskey 
3456ba597c5SAnurag S. Maskey 		/* Link NCU properties */
3466ba597c5SAnurag S. Maskey 		prop = NWAM_NCU_PROP_ACTIVATION_MODE;
3476ba597c5SAnurag S. Maskey 		uintval = NWAM_ACTIVATION_MODE_PRIORITIZED;
3486ba597c5SAnurag S. Maskey 		if ((err = nwamd_set_ncu_uint(phys_ncu, &uintval, 1, prop))
3496ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
3506ba597c5SAnurag S. Maskey 			break;
3516ba597c5SAnurag S. Maskey 
3526ba597c5SAnurag S. Maskey 		prop = NWAM_NCU_PROP_PRIORITY_MODE;
3536ba597c5SAnurag S. Maskey 		uintval = NWAM_PRIORITY_MODE_EXCLUSIVE;
3546ba597c5SAnurag S. Maskey 		if ((err = nwamd_set_ncu_uint(phys_ncu, &uintval, 1, prop))
3556ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
3566ba597c5SAnurag S. Maskey 			break;
3576ba597c5SAnurag S. Maskey 
3586ba597c5SAnurag S. Maskey 		prop = NWAM_NCU_PROP_PRIORITY_GROUP;
3596ba597c5SAnurag S. Maskey 		uintval = wp->llp_pri;
3606ba597c5SAnurag S. Maskey 		if ((err = nwamd_set_ncu_uint(phys_ncu, &uintval, 1, prop))
3616ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
3626ba597c5SAnurag S. Maskey 			break;
3636ba597c5SAnurag S. Maskey 
3646ba597c5SAnurag S. Maskey 		/* IP NCU properties */
3656ba597c5SAnurag S. Maskey 		if (wp->llp_ipv4addrstr != NULL) {
3666ba597c5SAnurag S. Maskey 			/* Set v4 address and specify static addrsrc */
3676ba597c5SAnurag S. Maskey 			prop = NWAM_NCU_PROP_IPV4_ADDRSRC;
3686ba597c5SAnurag S. Maskey 			uintval = NWAM_ADDRSRC_STATIC;
3696ba597c5SAnurag S. Maskey 			if ((err = nwamd_set_ncu_uint(ip_ncu, &uintval, 1,
3706ba597c5SAnurag S. Maskey 			    prop)) != NWAM_SUCCESS)
3716ba597c5SAnurag S. Maskey 				break;
3726ba597c5SAnurag S. Maskey 
3736ba597c5SAnurag S. Maskey 			prop = NWAM_NCU_PROP_IPV4_ADDR;
3746ba597c5SAnurag S. Maskey 			strval = wp->llp_ipv4addrstr;
3756ba597c5SAnurag S. Maskey 			if ((err = nwamd_set_ncu_string(ip_ncu, &strval, 1,
3766ba597c5SAnurag S. Maskey 			    prop)) != NWAM_SUCCESS)
3776ba597c5SAnurag S. Maskey 				break;
3786ba597c5SAnurag S. Maskey 
3796ba597c5SAnurag S. Maskey 			static_configured = B_TRUE;
3806ba597c5SAnurag S. Maskey 		}
3816ba597c5SAnurag S. Maskey 
3826ba597c5SAnurag S. Maskey 		if (wp->llp_ipv6addrstr != NULL) {
3836ba597c5SAnurag S. Maskey 			/* Set v6 address and specify static addrsrc */
3846ba597c5SAnurag S. Maskey 			prop = NWAM_NCU_PROP_IPV6_ADDRSRC;
3856ba597c5SAnurag S. Maskey 			uintval = NWAM_ADDRSRC_STATIC;
3866ba597c5SAnurag S. Maskey 			if ((err = nwamd_set_ncu_uint(ip_ncu, &uintval, 1,
3876ba597c5SAnurag S. Maskey 			    prop)) != NWAM_SUCCESS)
3886ba597c5SAnurag S. Maskey 				break;
3896ba597c5SAnurag S. Maskey 
3906ba597c5SAnurag S. Maskey 			prop = NWAM_NCU_PROP_IPV6_ADDR;
3916ba597c5SAnurag S. Maskey 			strval = wp->llp_ipv6addrstr;
3926ba597c5SAnurag S. Maskey 			if ((err = nwamd_set_ncu_string(ip_ncu, &strval, 1,
3936ba597c5SAnurag S. Maskey 			    prop)) != NWAM_SUCCESS)
3946ba597c5SAnurag S. Maskey 				break;
3956ba597c5SAnurag S. Maskey 
3966ba597c5SAnurag S. Maskey 			static_configured = B_TRUE;
3976ba597c5SAnurag S. Maskey 		}
3986ba597c5SAnurag S. Maskey 
3996ba597c5SAnurag S. Maskey 		if (!wp->llp_ipv6onlink) {
4006ba597c5SAnurag S. Maskey 			prop = NWAM_NCU_PROP_IP_VERSION;
4016ba597c5SAnurag S. Maskey 			uintval = IPV4_VERSION;
4026ba597c5SAnurag S. Maskey 			if ((err = nwamd_set_ncu_uint(ip_ncu, &uintval, 1,
4036ba597c5SAnurag S. Maskey 			    prop)) != NWAM_SUCCESS)
4046ba597c5SAnurag S. Maskey 				break;
4056ba597c5SAnurag S. Maskey 		}
4066ba597c5SAnurag S. Maskey 
4076ba597c5SAnurag S. Maskey 		if ((err = nwam_ncu_commit(ip_ncu, 0)) != NWAM_SUCCESS ||
4086ba597c5SAnurag S. Maskey 		    (err = nwam_ncu_commit(phys_ncu, 0)) != NWAM_SUCCESS) {
4096ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "upgrade_llp_config: llp %s: "
4106ba597c5SAnurag S. Maskey 			    "could not commit NCUs: %s", wp->llp_lname,
4116ba597c5SAnurag S. Maskey 			    nwam_strerror(err));
4126ba597c5SAnurag S. Maskey 			/* Schedule a retry - root filesystem may be readonly */
4136ba597c5SAnurag S. Maskey 			llp_list_free();
4146ba597c5SAnurag S. Maskey 			nwam_ncu_free(ip_ncu);
4156ba597c5SAnurag S. Maskey 			nwam_ncu_free(phys_ncu);
416*71ed50cfSAnurag S. Maskey 			(void) nwam_ncp_destroy(user_ncp, 0);
417*71ed50cfSAnurag S. Maskey 			return (EAGAIN);
418*71ed50cfSAnurag S. Maskey 		}
4196ba597c5SAnurag S. Maskey 	}
4206ba597c5SAnurag S. Maskey 
4216ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
4226ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "upgrade_llp_config: llp %s: "
4236ba597c5SAnurag S. Maskey 		    "could not set value for property %s: %s", wp->llp_lname,
4246ba597c5SAnurag S. Maskey 		    prop, nwam_strerror(err));
4256ba597c5SAnurag S. Maskey 	}
4266ba597c5SAnurag S. Maskey 	llp_list_free();
427*71ed50cfSAnurag S. Maskey 	nwam_ncu_free(ip_ncu);
428*71ed50cfSAnurag S. Maskey 	nwam_ncu_free(phys_ncu);
429*71ed50cfSAnurag S. Maskey 	nwam_ncp_free(user_ncp);
4306ba597c5SAnurag S. Maskey 	return (0);
431b00044a2SJames Carlson }
432b00044a2SJames Carlson 
433b00044a2SJames Carlson /*
4346ba597c5SAnurag S. Maskey  * Upgrade legacy llp and known_wifi_nets files. Note - it is possible that
4356ba597c5SAnurag S. Maskey  * the root filesystem is not writable at this point, so we need to schedule
4366ba597c5SAnurag S. Maskey  * a retry of the upgrade operation in the event that committing the new
4376ba597c5SAnurag S. Maskey  * config fails.
438b00044a2SJames Carlson  */
4396ba597c5SAnurag S. Maskey /* ARGSUSED0 */
440b00044a2SJames Carlson void
4416ba597c5SAnurag S. Maskey nwamd_handle_upgrade(nwamd_event_t event)
442b00044a2SJames Carlson {
4436ba597c5SAnurag S. Maskey 	nwamd_event_t upgrade_event;
4446ba597c5SAnurag S. Maskey 	uint64_t dhcp_wait_time, idle_time;
4456ba597c5SAnurag S. Maskey 	boolean_t use_net_svc;
446b00044a2SJames Carlson 
4476ba597c5SAnurag S. Maskey 	switch (upgrade_llp_config()) {
4486ba597c5SAnurag S. Maskey 	case -1:
4496ba597c5SAnurag S. Maskey 	case ENOENT:
4506ba597c5SAnurag S. Maskey 		/* Nothing readable to upgrade */
4516ba597c5SAnurag S. Maskey 		break;
4526ba597c5SAnurag S. Maskey 	case EAGAIN:
4536ba597c5SAnurag S. Maskey 		/*
4546ba597c5SAnurag S. Maskey 		 * Schedule retry in NWAMD_READONLY_RETRY_INTERVAL seconds
4556ba597c5SAnurag S. Maskey 		 * as root fs may be readonly.
4566ba597c5SAnurag S. Maskey 		 *
4576ba597c5SAnurag S. Maskey 		 * The upgrade event is of type NCU, but has no associated
4586ba597c5SAnurag S. Maskey 		 * object (we use the event type to map to the appropriate
4596ba597c5SAnurag S. Maskey 		 * event/method mappings, so to find the NCU upgrade event
4606ba597c5SAnurag S. Maskey 		 * method we specify type NCU while not specifying an
4616ba597c5SAnurag S. Maskey 		 * object since all NCUs have to be upgraded.
4626ba597c5SAnurag S. Maskey 		 */
4636ba597c5SAnurag S. Maskey 		upgrade_event = nwamd_event_init(NWAM_EVENT_TYPE_UPGRADE,
4646ba597c5SAnurag S. Maskey 		    NWAM_OBJECT_TYPE_NCP, 0, NULL);
465*71ed50cfSAnurag S. Maskey 		if (upgrade_event == NULL) {
466*71ed50cfSAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_handle_upgrade: "
467*71ed50cfSAnurag S. Maskey 			    "could not create retry event to upgrade "
468*71ed50cfSAnurag S. Maskey 			    "%s configuration", LLPFILE);
4696ba597c5SAnurag S. Maskey 			return;
470*71ed50cfSAnurag S. Maskey 		}
4716ba597c5SAnurag S. Maskey 		nwamd_event_enqueue_timed(upgrade_event,
4726ba597c5SAnurag S. Maskey 		    NWAMD_READONLY_RETRY_INTERVAL);
4736ba597c5SAnurag S. Maskey 		return;
4746ba597c5SAnurag S. Maskey 	default:
4756ba597c5SAnurag S. Maskey 		break;
476b00044a2SJames Carlson 	}
477b00044a2SJames Carlson 
478b00044a2SJames Carlson 	/*
4796ba597c5SAnurag S. Maskey 	 * If static_configured is set, then at least one static address is
4806ba597c5SAnurag S. Maskey 	 * configured in /etc/nwam/llp.  Enable the User NCP in this case.
481b00044a2SJames Carlson 	 */
4826ba597c5SAnurag S. Maskey 	if (static_configured) {
4836ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_handle_upgrade: "
4846ba597c5SAnurag S. Maskey 		    "static address configured, enabling User NCP");
4856ba597c5SAnurag S. Maskey 		(void) pthread_mutex_lock(&active_ncp_mutex);
4866ba597c5SAnurag S. Maskey 		(void) strlcpy(active_ncp, NWAM_NCP_NAME_USER,
4876ba597c5SAnurag S. Maskey 		    NWAM_MAX_NAME_LEN);
4886ba597c5SAnurag S. Maskey 		(void) pthread_mutex_unlock(&active_ncp_mutex);
489b00044a2SJames Carlson 	}
4906ba597c5SAnurag S. Maskey 
4916ba597c5SAnurag S. Maskey 	/* upgrade /etc/nwam/known_wifi_nets */
4926ba597c5SAnurag S. Maskey 	upgrade_known_wifi_nets_config();
4936ba597c5SAnurag S. Maskey 
4946ba597c5SAnurag S. Maskey 	/*
4956ba597c5SAnurag S. Maskey 	 * SMF property nwamd/dhcp_wait_time in Phase 0/0.5 has been
4966ba597c5SAnurag S. Maskey 	 * replaced by nwamd/ncu_wait_time property.  If the dhcp_wait_time
4976ba597c5SAnurag S. Maskey 	 * property exists (which means it has been changed by the user),
4986ba597c5SAnurag S. Maskey 	 * set its value to ncu_wait_time and remove the property.
4996ba597c5SAnurag S. Maskey 	 */
5006ba597c5SAnurag S. Maskey 	if (nwamd_lookup_count_property(OUR_FMRI, OUR_PG,
5016ba597c5SAnurag S. Maskey 	    OUR_OLD_DHCP_WAIT_TIME_PROP_NAME, &dhcp_wait_time) == 0) {
5026ba597c5SAnurag S. Maskey 		(void) nwamd_set_count_property(OUR_FMRI, OUR_PG,
5036ba597c5SAnurag S. Maskey 		    OUR_NCU_WAIT_TIME_PROP_NAME, dhcp_wait_time);
5046ba597c5SAnurag S. Maskey 		(void) nwamd_delete_scf_property(OUR_FMRI, OUR_PG,
5056ba597c5SAnurag S. Maskey 		    OUR_OLD_DHCP_WAIT_TIME_PROP_NAME);
5066ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_handle_upgrade: "
5076ba597c5SAnurag S. Maskey 		    "converted '%s' to '%s' with value of %lld",
5086ba597c5SAnurag S. Maskey 		    OUR_OLD_DHCP_WAIT_TIME_PROP_NAME,
5096ba597c5SAnurag S. Maskey 		    OUR_NCU_WAIT_TIME_PROP_NAME, dhcp_wait_time);
510b00044a2SJames Carlson 	}
511b00044a2SJames Carlson 
512b00044a2SJames Carlson 	/*
5136ba597c5SAnurag S. Maskey 	 * If the user has changed Phase 0/0.5 properties that don't exist in
5146ba597c5SAnurag S. Maskey 	 * Phase 1, manifest-import reports a warning; but those properties are
5156ba597c5SAnurag S. Maskey 	 * not removed.  nwamd/use_net_svc and nwamd/idle_time are two
5166ba597c5SAnurag S. Maskey 	 * properties that don't exist in Phase 1.  If they exist, remove them.
517b00044a2SJames Carlson 	 */
5186ba597c5SAnurag S. Maskey 	if (nwamd_lookup_count_property(OUR_FMRI, OUR_PG,
5196ba597c5SAnurag S. Maskey 	    OUR_OLD_IDLE_TIME_PROP_NAME, &idle_time) == 0) {
5206ba597c5SAnurag S. Maskey 		(void) nwamd_delete_scf_property(OUR_FMRI, OUR_PG,
5216ba597c5SAnurag S. Maskey 		    OUR_OLD_IDLE_TIME_PROP_NAME);
5226ba597c5SAnurag S. Maskey 	}
5236ba597c5SAnurag S. Maskey 	if (nwamd_lookup_boolean_property(OUR_FMRI, OUR_PG,
5246ba597c5SAnurag S. Maskey 	    OUR_OLD_USE_NET_SVC_PROP_NAME, &use_net_svc) == 0) {
5256ba597c5SAnurag S. Maskey 		(void) nwamd_delete_scf_property(OUR_FMRI, OUR_PG,
5266ba597c5SAnurag S. Maskey 		    OUR_OLD_USE_NET_SVC_PROP_NAME);
5276ba597c5SAnurag S. Maskey 	}
528b00044a2SJames Carlson 
5296ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "nwamd_handle_upgrade: "
5306ba597c5SAnurag S. Maskey 	    "creating version property, setting to 1\n");
5316ba597c5SAnurag S. Maskey 	(void) nwamd_set_count_property(OUR_FMRI, OUR_PG,
5326ba597c5SAnurag S. Maskey 	    OUR_VERSION_PROP_NAME, 1U);
5336ba597c5SAnurag S. Maskey 	(void) smf_refresh_instance(OUR_FMRI);
534b00044a2SJames Carlson }
535