13938Sjbeck /*
23938Sjbeck * CDDL HEADER START
33938Sjbeck *
43938Sjbeck * The contents of this file are subject to the terms of the
53938Sjbeck * Common Development and Distribution License (the "License").
63938Sjbeck * You may not use this file except in compliance with the License.
73938Sjbeck *
83938Sjbeck * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93938Sjbeck * or http://www.opensolaris.org/os/licensing.
103938Sjbeck * See the License for the specific language governing permissions
113938Sjbeck * and limitations under the License.
123938Sjbeck *
133938Sjbeck * When distributing Covered Code, include this CDDL HEADER in each
143938Sjbeck * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153938Sjbeck * If applicable, add the following below this CDDL HEADER, with the
163938Sjbeck * fields enclosed by brackets "[]" replaced with your own identifying
173938Sjbeck * information: Portions Copyright [yyyy] [name of copyright owner]
183938Sjbeck *
193938Sjbeck * CDDL HEADER END
203938Sjbeck */
213938Sjbeck
223938Sjbeck /*
23*12371SAnurag.Maskey@Oracle.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
243938Sjbeck */
253938Sjbeck
263938Sjbeck /*
2711767SAnurag.Maskey@Sun.COM * This file is here for legacy support.
283938Sjbeck */
293938Sjbeck
3011767SAnurag.Maskey@Sun.COM #include <atomic.h>
313938Sjbeck #include <ctype.h>
323938Sjbeck #include <errno.h>
3311767SAnurag.Maskey@Sun.COM #include <limits.h>
3411767SAnurag.Maskey@Sun.COM #include <libdllink.h>
3511767SAnurag.Maskey@Sun.COM #include <libscf.h>
3611767SAnurag.Maskey@Sun.COM #include <stdio.h>
3711767SAnurag.Maskey@Sun.COM #include <stdlib.h>
3811767SAnurag.Maskey@Sun.COM #include <string.h>
3911767SAnurag.Maskey@Sun.COM #include <strings.h>
403938Sjbeck
4111767SAnurag.Maskey@Sun.COM #include <libnwam.h>
4211767SAnurag.Maskey@Sun.COM #include "known_wlans.h"
4311767SAnurag.Maskey@Sun.COM #include "llp.h"
4411767SAnurag.Maskey@Sun.COM #include "ncu.h"
4511767SAnurag.Maskey@Sun.COM #include "util.h"
463938Sjbeck
4711767SAnurag.Maskey@Sun.COM /*
4811767SAnurag.Maskey@Sun.COM * This file formerly contained the routines that manipulate Link Layer
4911767SAnurag.Maskey@Sun.COM * Profiles (aka LLPs) and various support functions. Now only code
5011767SAnurag.Maskey@Sun.COM * necessary for parsing the legacy /etc/nwam/llp file on upgrade is included,
5111767SAnurag.Maskey@Sun.COM * since this legacy configuration needs to be translated into the User NCP.
5211767SAnurag.Maskey@Sun.COM */
533938Sjbeck
5411767SAnurag.Maskey@Sun.COM #define OUR_OLD_DHCP_WAIT_TIME_PROP_NAME "dhcp_wait_time"
5511767SAnurag.Maskey@Sun.COM #define OUR_OLD_USE_NET_SVC_PROP_NAME "use_net_svc"
5611767SAnurag.Maskey@Sun.COM #define OUR_OLD_IDLE_TIME_PROP_NAME "idle_time"
577645Sjames.d.carlson@sun.com
587645Sjames.d.carlson@sun.com static struct qelem llp_list;
593938Sjbeck
603938Sjbeck /*
613938Sjbeck * Global variable to hold the highest priority. Need to use the atomic
623938Sjbeck * integer arithmetic functions to update it.
633938Sjbeck */
647645Sjames.d.carlson@sun.com static uint32_t llp_highest_pri;
653938Sjbeck
6611767SAnurag.Maskey@Sun.COM /* Specifies if static address has been configured in /etc/nwam/llp */
6711767SAnurag.Maskey@Sun.COM static boolean_t static_configured = B_FALSE;
6811767SAnurag.Maskey@Sun.COM
6911767SAnurag.Maskey@Sun.COM static enum interface_type
find_if_type(const char * name)7011767SAnurag.Maskey@Sun.COM find_if_type(const char *name)
7111767SAnurag.Maskey@Sun.COM {
7211767SAnurag.Maskey@Sun.COM uint32_t media;
7311767SAnurag.Maskey@Sun.COM enum interface_type type;
7411767SAnurag.Maskey@Sun.COM
7511767SAnurag.Maskey@Sun.COM if (name == NULL) {
7611767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "find_if_type: no ifname; "
7711767SAnurag.Maskey@Sun.COM "returning IF_UNKNOWN");
7811767SAnurag.Maskey@Sun.COM return (IF_UNKNOWN);
7911767SAnurag.Maskey@Sun.COM }
803938Sjbeck
8111767SAnurag.Maskey@Sun.COM type = IF_WIRED;
8211767SAnurag.Maskey@Sun.COM if (dladm_name2info(dld_handle, name, NULL, NULL, NULL, &media) !=
8311767SAnurag.Maskey@Sun.COM DLADM_STATUS_OK) {
8411767SAnurag.Maskey@Sun.COM if (strncmp(name, "ip.tun", 6) == 0 ||
8511767SAnurag.Maskey@Sun.COM strncmp(name, "ip6.tun", 7) == 0 ||
8611767SAnurag.Maskey@Sun.COM strncmp(name, "ip.6to4tun", 10) == 0)
8711767SAnurag.Maskey@Sun.COM /*
8811767SAnurag.Maskey@Sun.COM * We'll need to update our tunnel detection once
8911767SAnurag.Maskey@Sun.COM * the clearview/tun project is integrated; tunnel
9011767SAnurag.Maskey@Sun.COM * names won't necessarily be ip.tunN.
9111767SAnurag.Maskey@Sun.COM */
9211767SAnurag.Maskey@Sun.COM type = IF_TUN;
9311767SAnurag.Maskey@Sun.COM } else if (media == DL_WIFI) {
9411767SAnurag.Maskey@Sun.COM type = IF_WIRELESS;
9511767SAnurag.Maskey@Sun.COM }
9611767SAnurag.Maskey@Sun.COM
9711767SAnurag.Maskey@Sun.COM return (type);
987645Sjames.d.carlson@sun.com }
997645Sjames.d.carlson@sun.com
10011767SAnurag.Maskey@Sun.COM static void
llp_list_free(void)10111767SAnurag.Maskey@Sun.COM llp_list_free(void)
1023938Sjbeck {
10311767SAnurag.Maskey@Sun.COM llp_t *llp;
1043938Sjbeck
10511767SAnurag.Maskey@Sun.COM while (llp_list.q_forw != &llp_list) {
10611767SAnurag.Maskey@Sun.COM llp = (llp_t *)llp_list.q_forw;
1077645Sjames.d.carlson@sun.com remque(&llp->llp_links);
1087645Sjames.d.carlson@sun.com free(llp->llp_ipv6addrstr);
1097645Sjames.d.carlson@sun.com free(llp->llp_ipv4addrstr);
1107645Sjames.d.carlson@sun.com free(llp);
1117645Sjames.d.carlson@sun.com }
1127645Sjames.d.carlson@sun.com }
1133938Sjbeck
1147645Sjames.d.carlson@sun.com static void
initialize_llp(void)11511767SAnurag.Maskey@Sun.COM initialize_llp(void)
1167645Sjames.d.carlson@sun.com {
11711767SAnurag.Maskey@Sun.COM llp_list.q_forw = llp_list.q_back = &llp_list;
1183938Sjbeck }
1193938Sjbeck
12011767SAnurag.Maskey@Sun.COM static llp_t *
llp_lookup(const char * link)1213938Sjbeck llp_lookup(const char *link)
1223938Sjbeck {
1233938Sjbeck llp_t *llp;
1243938Sjbeck
1253938Sjbeck if (link == NULL)
1263938Sjbeck return (NULL);
1273938Sjbeck
1287645Sjames.d.carlson@sun.com for (llp = (llp_t *)llp_list.q_forw; llp != (llp_t *)&llp_list;
1297645Sjames.d.carlson@sun.com llp = (llp_t *)llp->llp_links.q_forw) {
1303938Sjbeck if (strcmp(link, llp->llp_lname) == 0)
1313938Sjbeck break;
1323938Sjbeck }
1337645Sjames.d.carlson@sun.com if (llp == (llp_t *)&llp_list)
1347645Sjames.d.carlson@sun.com llp = NULL;
1353938Sjbeck return (llp);
1363938Sjbeck }
1373938Sjbeck
1383938Sjbeck /*
1397645Sjames.d.carlson@sun.com * Create the named LLP with default settings. Called only in main thread.
1403938Sjbeck */
14111767SAnurag.Maskey@Sun.COM static llp_t *
llp_add(const char * name)1427645Sjames.d.carlson@sun.com llp_add(const char *name)
1433938Sjbeck {
1447645Sjames.d.carlson@sun.com llp_t *llp;
1453938Sjbeck
1467645Sjames.d.carlson@sun.com if ((llp = calloc(1, sizeof (llp_t))) == NULL) {
14711767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "llp_add: cannot allocate LLP: %m");
1487645Sjames.d.carlson@sun.com return (NULL);
1497645Sjames.d.carlson@sun.com }
1503938Sjbeck
1517645Sjames.d.carlson@sun.com if (strlcpy(llp->llp_lname, name, sizeof (llp->llp_lname)) >=
1527645Sjames.d.carlson@sun.com sizeof (llp->llp_lname)) {
15311767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "llp_add: linkname '%s' too long; ignoring entry",
1547645Sjames.d.carlson@sun.com name);
1557645Sjames.d.carlson@sun.com free(llp);
1567645Sjames.d.carlson@sun.com return (NULL);
1573938Sjbeck }
1583938Sjbeck
1597645Sjames.d.carlson@sun.com llp->llp_fileorder = llp->llp_pri =
1607645Sjames.d.carlson@sun.com atomic_add_32_nv(&llp_highest_pri, 1);
1617645Sjames.d.carlson@sun.com llp->llp_ipv4src = IPV4SRC_DHCP;
1627645Sjames.d.carlson@sun.com llp->llp_type = find_if_type(llp->llp_lname);
1637645Sjames.d.carlson@sun.com llp->llp_ipv6onlink = B_TRUE;
1643938Sjbeck
1653938Sjbeck /*
1663938Sjbeck * should be a no-op, but for now, make sure we only
1673938Sjbeck * create llps for wired and wireless interfaces.
1683938Sjbeck */
1697645Sjames.d.carlson@sun.com if (llp->llp_type != IF_WIRED && llp->llp_type != IF_WIRELESS) {
17011767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "llp_add: wrong type of interface for %s", name);
1717645Sjames.d.carlson@sun.com free(llp);
1727645Sjames.d.carlson@sun.com return (NULL);
1733938Sjbeck }
1747645Sjames.d.carlson@sun.com insque(&llp->llp_links, llp_list.q_back);
1753938Sjbeck
17611767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "llp_add: "
17711767SAnurag.Maskey@Sun.COM "created llp for link %s, priority %d", llp->llp_lname,
1787645Sjames.d.carlson@sun.com llp->llp_pri);
1797645Sjames.d.carlson@sun.com return (llp);
1803938Sjbeck }
1813938Sjbeck
18211767SAnurag.Maskey@Sun.COM static int
parse_llp_config(void)18311767SAnurag.Maskey@Sun.COM parse_llp_config(void)
1843938Sjbeck {
1853938Sjbeck static const char STATICSTR[] = "static";
1863938Sjbeck static const char DHCP[] = "dhcp";
1873938Sjbeck static const char IPV6[] = "ipv6";
1883938Sjbeck static const char NOIPV6[] = "noipv6";
1897645Sjames.d.carlson@sun.com static const char PRIORITY[] = "priority";
1903938Sjbeck FILE *fp;
1913938Sjbeck char line[LINE_MAX];
1927645Sjames.d.carlson@sun.com char *cp, *lasts, *lstr, *srcstr, *addrstr;
1933938Sjbeck int lnum;
1947645Sjames.d.carlson@sun.com llp_t *llp;
1957645Sjames.d.carlson@sun.com
19611767SAnurag.Maskey@Sun.COM initialize_llp();
1973938Sjbeck
1983938Sjbeck fp = fopen(LLPFILE, "r+");
1993938Sjbeck if (fp == NULL) {
20011767SAnurag.Maskey@Sun.COM if (errno == ENOENT)
20111767SAnurag.Maskey@Sun.COM return (errno);
20211767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: "
20311767SAnurag.Maskey@Sun.COM "open legacy LLP config file: %m");
20411767SAnurag.Maskey@Sun.COM return (-1);
2053938Sjbeck }
2063938Sjbeck
2073938Sjbeck for (lnum = 1; fgets(line, sizeof (line), fp) != NULL; lnum++) {
2083938Sjbeck if (line[strlen(line) - 1] == '\n')
2093938Sjbeck line[strlen(line) - 1] = '\0';
2103938Sjbeck
2113938Sjbeck cp = line;
2123938Sjbeck while (isspace(*cp))
2133938Sjbeck cp++;
2143938Sjbeck
2153938Sjbeck if (*cp == '#' || *cp == '\0')
2163938Sjbeck continue;
2173938Sjbeck
21811767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "parse_llp_config: "
21911767SAnurag.Maskey@Sun.COM "parsing legacy LLP conf file line %d...", lnum);
2203938Sjbeck
2213938Sjbeck if (((lstr = strtok_r(cp, " \t", &lasts)) == NULL) ||
2223938Sjbeck ((srcstr = strtok_r(NULL, " \t", &lasts)) == NULL)) {
22311767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: line %d: "
22411767SAnurag.Maskey@Sun.COM "not enough tokens; ignoring entry", lnum);
2253938Sjbeck continue;
2263938Sjbeck }
2277645Sjames.d.carlson@sun.com
2287645Sjames.d.carlson@sun.com if ((llp = llp_lookup(lstr)) == NULL &&
2297645Sjames.d.carlson@sun.com (llp = llp_add(lstr)) == NULL) {
23011767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: line %d: "
23111767SAnurag.Maskey@Sun.COM "cannot add entry", lnum);
2327645Sjames.d.carlson@sun.com continue;
2337645Sjames.d.carlson@sun.com }
2347645Sjames.d.carlson@sun.com
2353938Sjbeck if (strcasecmp(srcstr, STATICSTR) == 0) {
2363938Sjbeck if ((addrstr = strtok_r(NULL, " \t", &lasts)) == NULL ||
2373938Sjbeck atoi(addrstr) == 0) { /* crude check for number */
23811767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: line %d: "
23911767SAnurag.Maskey@Sun.COM "missing ipaddr for static config", lnum);
2407645Sjames.d.carlson@sun.com } else if ((addrstr = strdup(addrstr)) == NULL) {
24111767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: line %d: "
24211767SAnurag.Maskey@Sun.COM "cannot save address", lnum);
2437645Sjames.d.carlson@sun.com } else {
2447645Sjames.d.carlson@sun.com free(llp->llp_ipv4addrstr);
2457645Sjames.d.carlson@sun.com llp->llp_ipv4src = IPV4SRC_STATIC;
2467645Sjames.d.carlson@sun.com llp->llp_ipv4addrstr = addrstr;
2473938Sjbeck }
2487645Sjames.d.carlson@sun.com
2493938Sjbeck } else if (strcasecmp(srcstr, DHCP) == 0) {
2507645Sjames.d.carlson@sun.com llp->llp_ipv4src = IPV4SRC_DHCP;
2517645Sjames.d.carlson@sun.com
2523938Sjbeck } else if (strcasecmp(srcstr, IPV6) == 0) {
2537645Sjames.d.carlson@sun.com llp->llp_ipv6onlink = B_TRUE;
2547645Sjames.d.carlson@sun.com if ((addrstr = strtok_r(NULL, " \t", &lasts)) == NULL) {
2557645Sjames.d.carlson@sun.com (void) 0;
2567645Sjames.d.carlson@sun.com } else if ((addrstr = strdup(addrstr)) == NULL) {
25711767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: line %d: "
25811767SAnurag.Maskey@Sun.COM "cannot save address", lnum);
2593938Sjbeck } else {
2607645Sjames.d.carlson@sun.com free(llp->llp_ipv6addrstr);
2617645Sjames.d.carlson@sun.com llp->llp_ipv6addrstr = addrstr;
2623938Sjbeck }
2637645Sjames.d.carlson@sun.com
2643938Sjbeck } else if (strcasecmp(srcstr, NOIPV6) == 0) {
2657645Sjames.d.carlson@sun.com llp->llp_ipv6onlink = B_FALSE;
2667645Sjames.d.carlson@sun.com
2677645Sjames.d.carlson@sun.com } else if (strcasecmp(srcstr, PRIORITY) == 0) {
2687645Sjames.d.carlson@sun.com if ((addrstr = strtok_r(NULL, " \t", &lasts)) == NULL) {
26911767SAnurag.Maskey@Sun.COM nlog(LOG_ERR,
27011767SAnurag.Maskey@Sun.COM "parse_llp_config: line %d: "
27111767SAnurag.Maskey@Sun.COM "missing priority value", lnum);
2727645Sjames.d.carlson@sun.com } else {
2737645Sjames.d.carlson@sun.com llp->llp_pri = atoi(addrstr);
2747645Sjames.d.carlson@sun.com }
2757645Sjames.d.carlson@sun.com
2763938Sjbeck } else {
27711767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "parse_llp_config: line %d: "
27811767SAnurag.Maskey@Sun.COM "unrecognized field '%s'", lnum, srcstr);
2793938Sjbeck }
2803938Sjbeck }
2813938Sjbeck
2823938Sjbeck (void) fclose(fp);
28311767SAnurag.Maskey@Sun.COM return (0);
2847645Sjames.d.carlson@sun.com }
2857645Sjames.d.carlson@sun.com
2867645Sjames.d.carlson@sun.com /*
28711767SAnurag.Maskey@Sun.COM * Translate legacy LLP config into the user NCP.
2887645Sjames.d.carlson@sun.com */
28911767SAnurag.Maskey@Sun.COM static int
upgrade_llp_config(void)29011767SAnurag.Maskey@Sun.COM upgrade_llp_config(void)
2917645Sjames.d.carlson@sun.com {
29211767SAnurag.Maskey@Sun.COM llp_t *wp;
29311767SAnurag.Maskey@Sun.COM nwam_ncp_handle_t user_ncp;
29411767SAnurag.Maskey@Sun.COM nwam_ncu_handle_t phys_ncu = NULL, ip_ncu = NULL;
29511767SAnurag.Maskey@Sun.COM nwam_error_t err;
29611767SAnurag.Maskey@Sun.COM uint64_t uintval;
29711767SAnurag.Maskey@Sun.COM char *strval;
29811767SAnurag.Maskey@Sun.COM const char *prop;
2997645Sjames.d.carlson@sun.com
30011767SAnurag.Maskey@Sun.COM switch (parse_llp_config()) {
30111767SAnurag.Maskey@Sun.COM case -1:
30211767SAnurag.Maskey@Sun.COM return (0);
30311767SAnurag.Maskey@Sun.COM case ENOENT:
30411767SAnurag.Maskey@Sun.COM return (ENOENT);
30511767SAnurag.Maskey@Sun.COM default:
30611767SAnurag.Maskey@Sun.COM break;
30711767SAnurag.Maskey@Sun.COM }
308*12371SAnurag.Maskey@Oracle.COM
309*12371SAnurag.Maskey@Oracle.COM err = nwam_ncp_create(NWAM_NCP_NAME_USER, 0, &user_ncp);
310*12371SAnurag.Maskey@Oracle.COM switch (err) {
311*12371SAnurag.Maskey@Oracle.COM case NWAM_SUCCESS:
312*12371SAnurag.Maskey@Oracle.COM break;
313*12371SAnurag.Maskey@Oracle.COM case NWAM_ERROR_BIND:
314*12371SAnurag.Maskey@Oracle.COM case NWAM_ERROR_INTERNAL:
31511767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "upgrade_llp_config: "
316*12371SAnurag.Maskey@Oracle.COM "could not create User NCP: %s", nwam_strerror(err));
317*12371SAnurag.Maskey@Oracle.COM llp_list_free();
318*12371SAnurag.Maskey@Oracle.COM return (EAGAIN);
319*12371SAnurag.Maskey@Oracle.COM default:
320*12371SAnurag.Maskey@Oracle.COM nlog(LOG_ERR, "upgrade_llp_config: error creating User NCP: %s",
321*12371SAnurag.Maskey@Oracle.COM nwam_strerror(err));
32211767SAnurag.Maskey@Sun.COM llp_list_free();
32311767SAnurag.Maskey@Sun.COM return (0);
3247645Sjames.d.carlson@sun.com }
32511767SAnurag.Maskey@Sun.COM
32611767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "upgrade_llp_config: walking llp list");
32711767SAnurag.Maskey@Sun.COM
32811767SAnurag.Maskey@Sun.COM for (wp = (llp_t *)llp_list.q_forw; wp != (llp_t *)&llp_list;
32911767SAnurag.Maskey@Sun.COM wp = (llp_t *)wp->llp_links.q_forw) {
33011767SAnurag.Maskey@Sun.COM
33111767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "upgrade_llp_config: "
33211767SAnurag.Maskey@Sun.COM "upgrading llp %s", wp->llp_lname);
3337645Sjames.d.carlson@sun.com
33411767SAnurag.Maskey@Sun.COM if (nwam_ncu_create(user_ncp, wp->llp_lname,
33511767SAnurag.Maskey@Sun.COM NWAM_NCU_TYPE_INTERFACE, NWAM_NCU_CLASS_IP, &ip_ncu)
33611767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS ||
33711767SAnurag.Maskey@Sun.COM nwam_ncu_create(user_ncp, wp->llp_lname, NWAM_NCU_TYPE_LINK,
33811767SAnurag.Maskey@Sun.COM NWAM_NCU_CLASS_PHYS, &phys_ncu) != NWAM_SUCCESS) {
33911767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "upgrade_llp_config: llp %s: "
34011767SAnurag.Maskey@Sun.COM "could not create NCUs: %s", wp->llp_lname,
34111767SAnurag.Maskey@Sun.COM nwam_strerror(err));
34211767SAnurag.Maskey@Sun.COM break;
34311767SAnurag.Maskey@Sun.COM }
3447645Sjames.d.carlson@sun.com
34511767SAnurag.Maskey@Sun.COM /* Link NCU properties */
34611767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_ACTIVATION_MODE;
34711767SAnurag.Maskey@Sun.COM uintval = NWAM_ACTIVATION_MODE_PRIORITIZED;
34811767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_uint(phys_ncu, &uintval, 1, prop))
34911767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS)
35011767SAnurag.Maskey@Sun.COM break;
35111767SAnurag.Maskey@Sun.COM
35211767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_PRIORITY_MODE;
35311767SAnurag.Maskey@Sun.COM uintval = NWAM_PRIORITY_MODE_EXCLUSIVE;
35411767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_uint(phys_ncu, &uintval, 1, prop))
35511767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS)
35611767SAnurag.Maskey@Sun.COM break;
35711767SAnurag.Maskey@Sun.COM
35811767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_PRIORITY_GROUP;
35911767SAnurag.Maskey@Sun.COM uintval = wp->llp_pri;
36011767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_uint(phys_ncu, &uintval, 1, prop))
36111767SAnurag.Maskey@Sun.COM != NWAM_SUCCESS)
36211767SAnurag.Maskey@Sun.COM break;
3637645Sjames.d.carlson@sun.com
36411767SAnurag.Maskey@Sun.COM /* IP NCU properties */
36511767SAnurag.Maskey@Sun.COM if (wp->llp_ipv4addrstr != NULL) {
36611767SAnurag.Maskey@Sun.COM /* Set v4 address and specify static addrsrc */
36711767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_IPV4_ADDRSRC;
36811767SAnurag.Maskey@Sun.COM uintval = NWAM_ADDRSRC_STATIC;
36911767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_uint(ip_ncu, &uintval, 1,
37011767SAnurag.Maskey@Sun.COM prop)) != NWAM_SUCCESS)
37111767SAnurag.Maskey@Sun.COM break;
37211767SAnurag.Maskey@Sun.COM
37311767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_IPV4_ADDR;
37411767SAnurag.Maskey@Sun.COM strval = wp->llp_ipv4addrstr;
37511767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_string(ip_ncu, &strval, 1,
37611767SAnurag.Maskey@Sun.COM prop)) != NWAM_SUCCESS)
37711767SAnurag.Maskey@Sun.COM break;
37811767SAnurag.Maskey@Sun.COM
37911767SAnurag.Maskey@Sun.COM static_configured = B_TRUE;
38011767SAnurag.Maskey@Sun.COM }
38111767SAnurag.Maskey@Sun.COM
38211767SAnurag.Maskey@Sun.COM if (wp->llp_ipv6addrstr != NULL) {
38311767SAnurag.Maskey@Sun.COM /* Set v6 address and specify static addrsrc */
38411767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_IPV6_ADDRSRC;
38511767SAnurag.Maskey@Sun.COM uintval = NWAM_ADDRSRC_STATIC;
38611767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_uint(ip_ncu, &uintval, 1,
38711767SAnurag.Maskey@Sun.COM prop)) != NWAM_SUCCESS)
38811767SAnurag.Maskey@Sun.COM break;
38911767SAnurag.Maskey@Sun.COM
39011767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_IPV6_ADDR;
39111767SAnurag.Maskey@Sun.COM strval = wp->llp_ipv6addrstr;
39211767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_string(ip_ncu, &strval, 1,
39311767SAnurag.Maskey@Sun.COM prop)) != NWAM_SUCCESS)
39411767SAnurag.Maskey@Sun.COM break;
39511767SAnurag.Maskey@Sun.COM
39611767SAnurag.Maskey@Sun.COM static_configured = B_TRUE;
39711767SAnurag.Maskey@Sun.COM }
39811767SAnurag.Maskey@Sun.COM
39911767SAnurag.Maskey@Sun.COM if (!wp->llp_ipv6onlink) {
40011767SAnurag.Maskey@Sun.COM prop = NWAM_NCU_PROP_IP_VERSION;
40111767SAnurag.Maskey@Sun.COM uintval = IPV4_VERSION;
40211767SAnurag.Maskey@Sun.COM if ((err = nwamd_set_ncu_uint(ip_ncu, &uintval, 1,
40311767SAnurag.Maskey@Sun.COM prop)) != NWAM_SUCCESS)
40411767SAnurag.Maskey@Sun.COM break;
40511767SAnurag.Maskey@Sun.COM }
40611767SAnurag.Maskey@Sun.COM
40711767SAnurag.Maskey@Sun.COM if ((err = nwam_ncu_commit(ip_ncu, 0)) != NWAM_SUCCESS ||
40811767SAnurag.Maskey@Sun.COM (err = nwam_ncu_commit(phys_ncu, 0)) != NWAM_SUCCESS) {
40911767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "upgrade_llp_config: llp %s: "
41011767SAnurag.Maskey@Sun.COM "could not commit NCUs: %s", wp->llp_lname,
41111767SAnurag.Maskey@Sun.COM nwam_strerror(err));
41211767SAnurag.Maskey@Sun.COM /* Schedule a retry - root filesystem may be readonly */
41311767SAnurag.Maskey@Sun.COM llp_list_free();
414*12371SAnurag.Maskey@Oracle.COM nwam_ncu_free(ip_ncu);
415*12371SAnurag.Maskey@Oracle.COM nwam_ncu_free(phys_ncu);
416*12371SAnurag.Maskey@Oracle.COM (void) nwam_ncp_destroy(user_ncp, 0);
41711767SAnurag.Maskey@Sun.COM return (EAGAIN);
41811767SAnurag.Maskey@Sun.COM }
4197645Sjames.d.carlson@sun.com }
42011767SAnurag.Maskey@Sun.COM
42111767SAnurag.Maskey@Sun.COM if (err != NWAM_SUCCESS) {
42211767SAnurag.Maskey@Sun.COM nlog(LOG_ERR, "upgrade_llp_config: llp %s: "
42311767SAnurag.Maskey@Sun.COM "could not set value for property %s: %s", wp->llp_lname,
42411767SAnurag.Maskey@Sun.COM prop, nwam_strerror(err));
4257645Sjames.d.carlson@sun.com }
42611767SAnurag.Maskey@Sun.COM llp_list_free();
427*12371SAnurag.Maskey@Oracle.COM nwam_ncu_free(ip_ncu);
428*12371SAnurag.Maskey@Oracle.COM nwam_ncu_free(phys_ncu);
429*12371SAnurag.Maskey@Oracle.COM nwam_ncp_free(user_ncp);
43011767SAnurag.Maskey@Sun.COM return (0);
4317645Sjames.d.carlson@sun.com }
4327645Sjames.d.carlson@sun.com
4337645Sjames.d.carlson@sun.com /*
43411767SAnurag.Maskey@Sun.COM * Upgrade legacy llp and known_wifi_nets files. Note - it is possible that
43511767SAnurag.Maskey@Sun.COM * the root filesystem is not writable at this point, so we need to schedule
43611767SAnurag.Maskey@Sun.COM * a retry of the upgrade operation in the event that committing the new
43711767SAnurag.Maskey@Sun.COM * config fails.
4387645Sjames.d.carlson@sun.com */
43911767SAnurag.Maskey@Sun.COM /* ARGSUSED0 */
4407645Sjames.d.carlson@sun.com void
nwamd_handle_upgrade(nwamd_event_t event)44111767SAnurag.Maskey@Sun.COM nwamd_handle_upgrade(nwamd_event_t event)
4427645Sjames.d.carlson@sun.com {
44311767SAnurag.Maskey@Sun.COM nwamd_event_t upgrade_event;
44411767SAnurag.Maskey@Sun.COM uint64_t dhcp_wait_time, idle_time;
44511767SAnurag.Maskey@Sun.COM boolean_t use_net_svc;
44611767SAnurag.Maskey@Sun.COM
44711767SAnurag.Maskey@Sun.COM switch (upgrade_llp_config()) {
44811767SAnurag.Maskey@Sun.COM case -1:
44911767SAnurag.Maskey@Sun.COM case ENOENT:
45011767SAnurag.Maskey@Sun.COM /* Nothing readable to upgrade */
45111767SAnurag.Maskey@Sun.COM break;
45211767SAnurag.Maskey@Sun.COM case EAGAIN:
45311767SAnurag.Maskey@Sun.COM /*
45411767SAnurag.Maskey@Sun.COM * Schedule retry in NWAMD_READONLY_RETRY_INTERVAL seconds
45511767SAnurag.Maskey@Sun.COM * as root fs may be readonly.
45611767SAnurag.Maskey@Sun.COM *
45711767SAnurag.Maskey@Sun.COM * The upgrade event is of type NCU, but has no associated
45811767SAnurag.Maskey@Sun.COM * object (we use the event type to map to the appropriate
45911767SAnurag.Maskey@Sun.COM * event/method mappings, so to find the NCU upgrade event
46011767SAnurag.Maskey@Sun.COM * method we specify type NCU while not specifying an
46111767SAnurag.Maskey@Sun.COM * object since all NCUs have to be upgraded.
46211767SAnurag.Maskey@Sun.COM */
46311767SAnurag.Maskey@Sun.COM upgrade_event = nwamd_event_init(NWAM_EVENT_TYPE_UPGRADE,
46411767SAnurag.Maskey@Sun.COM NWAM_OBJECT_TYPE_NCP, 0, NULL);
465*12371SAnurag.Maskey@Oracle.COM if (upgrade_event == NULL) {
466*12371SAnurag.Maskey@Oracle.COM nlog(LOG_ERR, "nwamd_handle_upgrade: "
467*12371SAnurag.Maskey@Oracle.COM "could not create retry event to upgrade "
468*12371SAnurag.Maskey@Oracle.COM "%s configuration", LLPFILE);
46911767SAnurag.Maskey@Sun.COM return;
470*12371SAnurag.Maskey@Oracle.COM }
47111767SAnurag.Maskey@Sun.COM nwamd_event_enqueue_timed(upgrade_event,
47211767SAnurag.Maskey@Sun.COM NWAMD_READONLY_RETRY_INTERVAL);
47311767SAnurag.Maskey@Sun.COM return;
47411767SAnurag.Maskey@Sun.COM default:
47511767SAnurag.Maskey@Sun.COM break;
47611767SAnurag.Maskey@Sun.COM }
4777645Sjames.d.carlson@sun.com
4787645Sjames.d.carlson@sun.com /*
47911767SAnurag.Maskey@Sun.COM * If static_configured is set, then at least one static address is
48011767SAnurag.Maskey@Sun.COM * configured in /etc/nwam/llp. Enable the User NCP in this case.
4817645Sjames.d.carlson@sun.com */
48211767SAnurag.Maskey@Sun.COM if (static_configured) {
48311767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "nwamd_handle_upgrade: "
48411767SAnurag.Maskey@Sun.COM "static address configured, enabling User NCP");
48511767SAnurag.Maskey@Sun.COM (void) pthread_mutex_lock(&active_ncp_mutex);
48611767SAnurag.Maskey@Sun.COM (void) strlcpy(active_ncp, NWAM_NCP_NAME_USER,
48711767SAnurag.Maskey@Sun.COM NWAM_MAX_NAME_LEN);
48811767SAnurag.Maskey@Sun.COM (void) pthread_mutex_unlock(&active_ncp_mutex);
48911767SAnurag.Maskey@Sun.COM }
4907645Sjames.d.carlson@sun.com
49111767SAnurag.Maskey@Sun.COM /* upgrade /etc/nwam/known_wifi_nets */
49211767SAnurag.Maskey@Sun.COM upgrade_known_wifi_nets_config();
4937645Sjames.d.carlson@sun.com
49411767SAnurag.Maskey@Sun.COM /*
49511767SAnurag.Maskey@Sun.COM * SMF property nwamd/dhcp_wait_time in Phase 0/0.5 has been
49611767SAnurag.Maskey@Sun.COM * replaced by nwamd/ncu_wait_time property. If the dhcp_wait_time
49711767SAnurag.Maskey@Sun.COM * property exists (which means it has been changed by the user),
49811767SAnurag.Maskey@Sun.COM * set its value to ncu_wait_time and remove the property.
49911767SAnurag.Maskey@Sun.COM */
50011767SAnurag.Maskey@Sun.COM if (nwamd_lookup_count_property(OUR_FMRI, OUR_PG,
50111767SAnurag.Maskey@Sun.COM OUR_OLD_DHCP_WAIT_TIME_PROP_NAME, &dhcp_wait_time) == 0) {
50211767SAnurag.Maskey@Sun.COM (void) nwamd_set_count_property(OUR_FMRI, OUR_PG,
50311767SAnurag.Maskey@Sun.COM OUR_NCU_WAIT_TIME_PROP_NAME, dhcp_wait_time);
50411767SAnurag.Maskey@Sun.COM (void) nwamd_delete_scf_property(OUR_FMRI, OUR_PG,
50511767SAnurag.Maskey@Sun.COM OUR_OLD_DHCP_WAIT_TIME_PROP_NAME);
50611767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "nwamd_handle_upgrade: "
50711767SAnurag.Maskey@Sun.COM "converted '%s' to '%s' with value of %lld",
50811767SAnurag.Maskey@Sun.COM OUR_OLD_DHCP_WAIT_TIME_PROP_NAME,
50911767SAnurag.Maskey@Sun.COM OUR_NCU_WAIT_TIME_PROP_NAME, dhcp_wait_time);
5107645Sjames.d.carlson@sun.com }
5117645Sjames.d.carlson@sun.com
51211767SAnurag.Maskey@Sun.COM /*
51311767SAnurag.Maskey@Sun.COM * If the user has changed Phase 0/0.5 properties that don't exist in
51411767SAnurag.Maskey@Sun.COM * Phase 1, manifest-import reports a warning; but those properties are
51511767SAnurag.Maskey@Sun.COM * not removed. nwamd/use_net_svc and nwamd/idle_time are two
51611767SAnurag.Maskey@Sun.COM * properties that don't exist in Phase 1. If they exist, remove them.
51711767SAnurag.Maskey@Sun.COM */
51811767SAnurag.Maskey@Sun.COM if (nwamd_lookup_count_property(OUR_FMRI, OUR_PG,
51911767SAnurag.Maskey@Sun.COM OUR_OLD_IDLE_TIME_PROP_NAME, &idle_time) == 0) {
52011767SAnurag.Maskey@Sun.COM (void) nwamd_delete_scf_property(OUR_FMRI, OUR_PG,
52111767SAnurag.Maskey@Sun.COM OUR_OLD_IDLE_TIME_PROP_NAME);
5227645Sjames.d.carlson@sun.com }
52311767SAnurag.Maskey@Sun.COM if (nwamd_lookup_boolean_property(OUR_FMRI, OUR_PG,
52411767SAnurag.Maskey@Sun.COM OUR_OLD_USE_NET_SVC_PROP_NAME, &use_net_svc) == 0) {
52511767SAnurag.Maskey@Sun.COM (void) nwamd_delete_scf_property(OUR_FMRI, OUR_PG,
52611767SAnurag.Maskey@Sun.COM OUR_OLD_USE_NET_SVC_PROP_NAME);
52711767SAnurag.Maskey@Sun.COM }
52811767SAnurag.Maskey@Sun.COM
52911767SAnurag.Maskey@Sun.COM nlog(LOG_DEBUG, "nwamd_handle_upgrade: "
53011767SAnurag.Maskey@Sun.COM "creating version property, setting to 1\n");
53111767SAnurag.Maskey@Sun.COM (void) nwamd_set_count_property(OUR_FMRI, OUR_PG,
53211767SAnurag.Maskey@Sun.COM OUR_VERSION_PROP_NAME, 1U);
53311767SAnurag.Maskey@Sun.COM (void) smf_refresh_instance(OUR_FMRI);
5347645Sjames.d.carlson@sun.com }
535