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