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
find_if_type(const char * name)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
llp_list_free(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
initialize_llp(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 *
llp_lookup(const char * link)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 *
llp_add(const char * name)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
parse_llp_config(void)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
upgrade_llp_config(void)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
nwamd_handle_upgrade(nwamd_event_t event)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