summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Johnston <rob.johnston@joyent.com>2017-12-13 23:43:54 +0000
committerRob Johnston <rob.johnston@joyent.com>2018-02-02 01:40:47 +0000
commit4a99ae161887bed6eed6dcb1699f188f023921a2 (patch)
tree28c667e4ad741ea8bf4eefd5813921cf6c78b75d
parent6afca163c6f9158c8d995916782cd765188cbdf1 (diff)
downloadillumos-joyent-4a99ae161887bed6eed6dcb1699f188f023921a2.tar.gz
OS-6527 Add plaform-specific topo map for Joyent-Storage-Platform-7001
OS-6511 extend ipmi enumerator module to enumerate a node for the service processor OS-6490 Implement topo module to enumerate dimms from smbios Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Joshua M. Clulow <jmc@joyent.com>
-rw-r--r--manifest5
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/hc.c3
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/libtopo.h6
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/mapfile-vers2
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_hc.h44
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_mod.c10
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_mod.h3
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_mod.map2
-rw-r--r--usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-chassis-hc-topology.xml43
-rw-r--r--usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-hc-topology.xml88
-rw-r--r--usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-slot-hc-topology.xml277
-rw-r--r--usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Makefile33
-rw-r--r--usr/src/lib/fm/topo/maps/Makefile3
-rw-r--r--usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/Makefile5
-rw-r--r--usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-hc-topology.xml9
-rw-r--r--usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-slot-hc-topology.xml277
-rw-r--r--usr/src/lib/fm/topo/maps/common/topology.dtd.15
-rw-r--r--usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml8
-rw-r--r--usr/src/lib/fm/topo/modules/common/Makefile3
-rw-r--r--usr/src/lib/fm/topo/modules/common/ipmi/Makefile5
-rw-r--r--usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c279
-rw-r--r--usr/src/lib/fm/topo/modules/common/smbios/Makefile22
-rw-r--r--usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c483
-rw-r--r--usr/src/lib/libipmi/common/ipmi_lancfg.c245
-rw-r--r--usr/src/lib/libipmi/common/libipmi.h14
-rw-r--r--usr/src/pkg/manifests/service-fault-management.mf19
26 files changed, 1860 insertions, 33 deletions
diff --git a/manifest b/manifest
index 13b46f9368..fcf2b535fe 100644
--- a/manifest
+++ b/manifest
@@ -5421,6 +5421,7 @@ f usr/lib/fm/topo/plugins/fac_prov_mptsas.so 0555 root bin
f usr/lib/fm/topo/plugins/ipmi.so 0555 root bin
f usr/lib/fm/topo/plugins/nic.so 0555 root bin
f usr/lib/fm/topo/plugins/ses.so 0555 root bin
+f usr/lib/fm/topo/plugins/smbios.so 0555 root bin
f usr/lib/fm/topo/plugins/xfp.so 0555 root bin
d usr/lib/fs 0755 root sys
d usr/lib/fs/autofs 0755 root sys
@@ -10162,9 +10163,13 @@ d usr/platform/i86pc/lib/fm/topo/maps 0755 root sys
f usr/platform/i86pc/lib/fm/topo/maps/Joyent-Compute-Platform-1101-disk-hc-topology.xml 0444 root sys
s usr/platform/i86pc/lib/fm/topo/maps/Joyent-Compute-Platform-3101-hc-topology.xml=./SSG-2028R-ACR24L-hc-topology.xml
s usr/platform/i86pc/lib/fm/topo/maps/Joyent-Compute-Platform-3102-hc-topology.xml=./SSG-2028R-ACR24L-hc-topology.xml
+f usr/platform/i86pc/lib/fm/topo/maps/Joyent-Storage-Platform-7001-hc-topology.xml 0444 root sys
+f usr/platform/i86pc/lib/fm/topo/maps/Joyent-Storage-Platform-7001-chassis-hc-topology.xml 0444 root sys
+f usr/platform/i86pc/lib/fm/topo/maps/Joyent-Storage-Platform-7001-slot-hc-topology.xml 0444 root sys
f usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-hc-topology.xml 0444 root sys
f usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-chassis-hc-topology.xml 0444 root sys
f usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-disk-hc-topology.xml 0444 root sys
+f usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-slot-hc-topology.xml 0444 root sys
f usr/platform/i86pc/lib/fm/topo/maps/chassis-hc-topology.xml 0444 root sys
f usr/platform/i86pc/lib/fm/topo/maps/chip-hc-topology.xml 0444 root sys
f usr/platform/i86pc/lib/fm/topo/maps/fan-hc-topology.xml 0444 root sys
diff --git a/usr/src/lib/fm/topo/libtopo/common/hc.c b/usr/src/lib/fm/topo/libtopo/common/hc.c
index df718d6490..b9001f0fd2 100644
--- a/usr/src/lib/fm/topo/libtopo/common/hc.c
+++ b/usr/src/lib/fm/topo/libtopo/common/hc.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Joyent, Inc.
+ * Copyright (c) 2018, Joyent, Inc.
*/
#include <stdio.h>
@@ -191,6 +191,7 @@ static const hcc_t hc_canon[] = {
{ SCSI_DEVICE, TOPO_STABILITY_PRIVATE },
{ SHELF, TOPO_STABILITY_PRIVATE },
{ SES_ENCLOSURE, TOPO_STABILITY_PRIVATE },
+ { SLOT, TOPO_STABILITY_PRIVATE },
{ SMP_DEVICE, TOPO_STABILITY_PRIVATE },
{ SP, TOPO_STABILITY_PRIVATE },
{ STRAND, TOPO_STABILITY_PRIVATE },
diff --git a/usr/src/lib/fm/topo/libtopo/common/libtopo.h b/usr/src/lib/fm/topo/libtopo/common/libtopo.h
index e0adb6e0ab..da6083a5be 100644
--- a/usr/src/lib/fm/topo/libtopo/common/libtopo.h
+++ b/usr/src/lib/fm/topo/libtopo/common/libtopo.h
@@ -23,7 +23,7 @@
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBTOPO_H
@@ -1001,6 +1001,10 @@ typedef enum topo_led_type {
TOPO_LED_TYPE_PRESENT
} topo_led_type_t;
+typedef enum topo_slot_type {
+ TOPO_SLOT_TYPE_DIMM = 1
+} topo_slot_type_t;
+
#ifdef __cplusplus
}
diff --git a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers
index c6ff800951..26bba754a1 100644
--- a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers
+++ b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2018, Joyent, Inc.
#
#
@@ -90,6 +91,7 @@ SYMBOL_VERSION SUNWprivate {
topo_method_unregister_all;
topo_mod_alloc;
topo_mod_auth;
+ topo_mod_clean_str;
topo_mod_clrdebug;
topo_mod_cpufmri;
topo_mod_devfmri;
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h
index a9fdeb02d8..e0efd3f79d 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Joyent, Inc.
+ * Copyright (c) 2018, Joyent, Inc.
*/
#ifndef _TOPO_HC_H
@@ -87,6 +87,7 @@ extern "C" {
#define SHELF "shelf"
#define SCSI_DEVICE "scsi-device"
#define SES_ENCLOSURE "ses-enclosure"
+#define SLOT "slot"
#define SMP_DEVICE "smp-device"
#define SP "sp"
#define SUBCHASSIS "subchassis"
@@ -190,6 +191,47 @@ extern "C" {
*/
#define TOPO_PROP_IPMI_ENTITY_LIST "entity-list"
+/*
+ * These properties can be used to describe the network configuration of a
+ * given hardware components. They're currently used to describe the
+ * network config on the service processor (sp)
+ */
+#define TOPO_PGROUP_NETCFG "network-config"
+#define TOPO_PROP_NETCFG_MACADDR "mac-address"
+#define TOPO_PROP_NETCFG_VLAN_ID "vlan-id"
+#define TOPO_PROP_NETCFG_IPV4_ADDR "ipv4-address"
+#define TOPO_PROP_NETCFG_IPV4_SUBNET "ipv4-subnet"
+#define TOPO_PROP_NETCFG_IPV4_GATEWAY "ipv4-gateway"
+#define TOPO_PROP_NETCFG_IPV4_TYPE "ipv4-config-type"
+#define TOPO_PROP_NETCFG_IPV6_ADDR "ipv6-address"
+#define TOPO_PROP_NETCFG_IPV6_ROUTES "ipv6-routes"
+#define TOPO_PROP_NETCFG_IPV6_TYPE "ipv6-config-type"
+
+/* Possible values for TOPO_PROP_NETCFG_TYPE */
+#define TOPO_NETCFG_TYPE_UNKNOWN "unknown"
+#define TOPO_NETCFG_TYPE_STATIC "static"
+#define TOPO_NETCFG_TYPE_DHCP "dhcp"
+
+#define TOPO_PGROUP_SLOT "slot"
+#define TOPO_PROP_SLOT_TYPE "slot-type"
+
+#define TOPO_PGROUP_DIMM_SLOT "dimm-slot"
+#define TOPO_PROP_DIMM_SLOT_FORM "form-factor"
+#define TOPO_DIMM_SLOT_FORM_DIMM "DIMM"
+#define TOPO_DIMM_SLOT_FORM_SODIMM "SODIMM"
+#define TOPO_DIMM_SLOT_FORM_FBDIMM "FBDIMM"
+
+#define TOPO_PROP_DIMM_TYPE
+#define TOPO_DIMM_TYPE_UNKNOWN "UNKNOWN"
+#define TOPO_DIMM_TYPE_DDR "DDR"
+#define TOPO_DIMM_TYPE_DDR2 "DDR2"
+#define TOPO_DIMM_TYPE_DDR3 "DDR3"
+#define TOPO_DIMM_TYPE_DDR4 "DDR4"
+#define TOPO_DIMM_TYPE_LPDDR "LPDDR"
+#define TOPO_DIMM_TYPE_LPDDR2 "LPDDR2"
+#define TOPO_DIMM_TYPE_LPDDR3 "LPDDR3"
+#define TOPO_DIMM_TYPE_LPDDR4 "LPDDR4"
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.c b/usr/src/lib/fm/topo/libtopo/common/topo_mod.c
index 295054dc5e..0fef1f7ca0 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.c
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
*/
/*
@@ -896,3 +897,12 @@ topo_mod_walk_init(topo_mod_t *mod, tnode_t *node, topo_mod_walk_cb_t cb_f,
return (wp);
}
+
+char *
+topo_mod_clean_str(topo_mod_t *mod, const char *str)
+{
+ if (str == NULL)
+ return (NULL);
+
+ return (topo_cleanup_auth_str(mod->tm_hdl, str));
+}
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h
index e6dda440a0..517a593caf 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h
@@ -23,7 +23,7 @@
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc. All rights reserved.
*/
#ifndef _TOPO_MOD_H
@@ -228,6 +228,7 @@ extern void topo_mod_setdebug(topo_mod_t *);
extern void topo_mod_dprintf(topo_mod_t *, const char *, ...);
extern const char *topo_mod_errmsg(topo_mod_t *);
extern int topo_mod_errno(topo_mod_t *);
+extern char *topo_mod_clean_str(topo_mod_t *, const char *);
/*
* Topo node utilities: callable from module enumeration, topo_mod_enumerate()
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.map b/usr/src/lib/fm/topo/libtopo/common/topo_mod.map
index 44b62bdf7f..1e5920c27b 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.map
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.map
@@ -1,5 +1,6 @@
#
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2018, Joyent, Inc.
#
# CDDL HEADER START
#
@@ -64,6 +65,7 @@ SYMBOL_SCOPE {
topo_mod_nvl2str { TYPE = FUNCTION; FLAGS = extern };
topo_mod_str2nvl { TYPE = FUNCTION; FLAGS = extern };
topo_mod_auth { TYPE = FUNCTION; FLAGS = extern };
+ topo_mod_clean_str { TYPE = FUNCTION; FLAGS = extern };
topo_mod_walk_init { TYPE = FUNCTION; FLAGS = extern };
diff --git a/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-chassis-hc-topology.xml b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-chassis-hc-topology.xml
new file mode 100644
index 0000000000..d71085a615
--- /dev/null
+++ b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-chassis-hc-topology.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
+<!--
+
+ This file and its contents are supplied under the terms of the
+ Common Development and Distribution License ("CDDL"), version 1.0.
+ You may only use this file in accordance with the terms of version
+ 1.0 of the CDDL.
+
+ A full copy of the text of the CDDL should have accompanied this
+ source. A copy of the CDDL is also available via the Internet at
+ http://www.illumos.org/license/CDDL.
+
+ Copyright (c) 2018, Joyent, Inc.
+
+-->
+
+<topology name='chassis' scheme='hc'>
+ <range name='chassis' min='0' max='0'>
+ <node instance='0'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <!--
+ chassis locate LED
+ -->
+ <facility name='locate' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private'
+ data-stability='Private' >
+ <propval name='type' type='uint32' value='1' />
+ <propmethod name='chassis_ident_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='Chassis Intru' />
+ <propitem value='System Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+</topology>
diff --git a/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-hc-topology.xml b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-hc-topology.xml
new file mode 100644
index 0000000000..c185c50792
--- /dev/null
+++ b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-hc-topology.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
+<!--
+
+ This file and its contents are supplied under the terms of the
+ Common Development and Distribution License ("CDDL"), version 1.0.
+ You may only use this file in accordance with the terms of version
+ 1.0 of the CDDL.
+
+ A full copy of the text of the CDDL should have accompanied this
+ source. A copy of the CDDL is also available via the Internet at
+ http://www.illumos.org/license/CDDL.
+
+ Copyright (c) 2018, Joyent, Inc.
+
+-->
+
+<topology name='i86pc' scheme='hc'>
+
+ <range name='motherboard' min='0' max='0'>
+ <node instance='0'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='label' type='string' value='MB' />
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='MB_10G Temp' />
+ <propitem value='PCH Temp' />
+ <propitem value='Peripheral Temp' />
+ <propitem value='5VSB' />
+ <propitem value='5VSB' />
+ <propitem value='3.3VSB' />
+ <propitem value='3.3VCC' />
+ <propitem value='1.5V PCH' />
+ <propitem value='1.2V BMC' />
+ <propitem value='1.05V PCH' />
+ <propitem value='12V' />
+ <propitem value='5VCC' />
+ <propitem value='VBAT' />
+ <propitem value='VDIMMAB' />
+ <propitem value='VDIMMCD' />
+ <propitem value='VDIMMEF' />
+ <propitem value='VDIMMGH' />
+ </propval>
+ </propgroup>
+ </node>
+
+ <dependents grouping='children'>
+ <range name='chip' min='0' max='1'>
+ <enum-method name='chip' version='1' />
+ </range>
+ <range name='hostbridge' min='0' max='254'>
+ <enum-method name='hostbridge' version='1' />
+ </range>
+ <range name='sp' min='0' max='0'>
+ <enum-method name='ipmi' version='1' />
+ </range>
+ <range name='slot' min='0' max='15'>
+ <enum-method name='smbios' version='1' />
+ <propmap name='Joyent-Storage-Platform-7001-slot' />
+ </range>
+ </dependents>
+
+ </range>
+
+ <range name='chassis' min='0' max='0'>
+ <propmap name='Joyent-Storage-Platform-7001-chassis' />
+
+ <dependents grouping='children'>
+
+ <range name='psu' min='0' max='1'>
+ <enum-method name='ipmi' version='1' />
+ </range>
+ <range name='fan' min='0' max='7'>
+ <enum-method name='ipmi' version='1' />
+ </range>
+
+ </dependents>
+ </range>
+
+ <range name='ses-enclosure' min='0' max='1'>
+ <enum-method name='ses' version='1' />
+ </range>
+
+</topology>
diff --git a/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-slot-hc-topology.xml b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-slot-hc-topology.xml
new file mode 100644
index 0000000000..6b16063427
--- /dev/null
+++ b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Joyent-Storage-Platform-7001-slot-hc-topology.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
+<!--
+
+ This file and its contents are supplied under the terms of the
+ Common Development and Distribution License ("CDDL"), version 1.0.
+ You may only use this file in accordance with the terms of version
+ 1.0 of the CDDL.
+
+ A full copy of the text of the CDDL should have accompanied this
+ source. A copy of the CDDL is also available via the Internet at
+ http://www.illumos.org/license/CDDL.
+
+ Copyright (c) 2018, Joyent, Inc.
+
+-->
+
+<topology name='slot' scheme='hc'>
+ <range name='slot' min='0' max='15'>
+ <node instance='0' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMA1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='1' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMA2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='2' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMB1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='3' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMB2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='4' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMC1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='5' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMC2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='6' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMD1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='7' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMD2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='8' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMME1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='9' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMME2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='10' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMF1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='11' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMF1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='12' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMG1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='13' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMG2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='14' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMH1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='15' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMH2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ </range> <!-- slot -->
+</topology>
diff --git a/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Makefile b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Makefile
new file mode 100644
index 0000000000..bffc198721
--- /dev/null
+++ b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Storage-Platform-7001/Makefile
@@ -0,0 +1,33 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2018, Joyent, Inc.
+#
+
+# NOTE: The name of the xml file we are building is 'platform'
+# specific, but its build is structured as 'arch' specific since
+# 'uname -i' on all x86 platforms returns i86pc.
+
+ARCH = i86pc
+CLASS = arch
+DTDFILE = topology.dtd.1
+
+TOPOFILE = \
+ Joyent-Storage-Platform-7001-hc-topology.xml \
+ Joyent-Storage-Platform-7001-chassis-hc-topology.xml \
+ Joyent-Storage-Platform-7001-slot-hc-topology.xml
+
+SRCDIR = ../Joyent,Joyent-Storage-Platform-7001
+
+PLATFORM = Joyent-Storage-Platform-7001
+
+include ../Makefile.map
diff --git a/usr/src/lib/fm/topo/maps/Makefile b/usr/src/lib/fm/topo/maps/Makefile
index 7cf2a33dbe..49b86186a1 100644
--- a/usr/src/lib/fm/topo/maps/Makefile
+++ b/usr/src/lib/fm/topo/maps/Makefile
@@ -22,7 +22,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-# Copyright (c) 2017, Joyent, Inc.
+# Copyright (c) 2018, Joyent, Inc.
#
sparc_SUBDIRS = sun4u \
@@ -51,6 +51,7 @@ i386_SUBDIRS = i86pc \
SUNW,Sun-Fire-X4540 \
SUNW,Sun-Fire-X4600-M2 \
Joyent,Joyent-Compute-Platform-1101 \
+ Joyent,Joyent-Storage-Platform-7001 \
SMCI,SSG-2028R-ACR24L
SUBDIRS = $($(MACH)_SUBDIRS)
diff --git a/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/Makefile b/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/Makefile
index 66492c6a82..15401c3abb 100644
--- a/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/Makefile
+++ b/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/Makefile
@@ -22,7 +22,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-# Copyright (c) 2017, Joyent, Inc.
+# Copyright (c) 2018, Joyent, Inc.
#
# NOTE: The name of the xml file we are building is 'platform'
@@ -41,7 +41,8 @@ ROOTJOYENTMAPS = $(JOYENT_PLATFORMS:%=$(arch_ROOTTOPOROOT)/%)
TOPOFILE = \
SSG-2028R-ACR24L-hc-topology.xml \
SSG-2028R-ACR24L-chassis-hc-topology.xml \
- SSG-2028R-ACR24L-disk-hc-topology.xml
+ SSG-2028R-ACR24L-disk-hc-topology.xml \
+ SSG-2028R-ACR24L-slot-hc-topology.xml
SRCDIR = ../SMCI,SSG-2028R-ACR24L
diff --git a/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-hc-topology.xml b/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-hc-topology.xml
index 8a77d285a5..83bc2e217b 100644
--- a/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-hc-topology.xml
+++ b/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-hc-topology.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
<!--
-Copyright (c) 2017, Joyent, Inc.
+Copyright (c) 2018, Joyent, Inc.
CDDL HEADER START
@@ -64,6 +64,13 @@ Copyright (c) 2017, Joyent, Inc.
<range name='hostbridge' min='0' max='254'>
<enum-method name='hostbridge' version='1' />
</range>
+ <range name='sp' min='0' max='0'>
+ <enum-method name='ipmi' version='1' />
+ </range>
+ <range name='slot' min='0' max='15'>
+ <enum-method name='smbios' version='1' />
+ <propmap name='SSG-2028R-ACR24L-slot' />
+ </range>
</dependents>
</range>
diff --git a/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-slot-hc-topology.xml b/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-slot-hc-topology.xml
new file mode 100644
index 0000000000..6b16063427
--- /dev/null
+++ b/usr/src/lib/fm/topo/maps/SMCI,SSG-2028R-ACR24L/SSG-2028R-ACR24L-slot-hc-topology.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0"?>
+<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
+<!--
+
+ This file and its contents are supplied under the terms of the
+ Common Development and Distribution License ("CDDL"), version 1.0.
+ You may only use this file in accordance with the terms of version
+ 1.0 of the CDDL.
+
+ A full copy of the text of the CDDL should have accompanied this
+ source. A copy of the CDDL is also available via the Internet at
+ http://www.illumos.org/license/CDDL.
+
+ Copyright (c) 2018, Joyent, Inc.
+
+-->
+
+<topology name='slot' scheme='hc'>
+ <range name='slot' min='0' max='15'>
+ <node instance='0' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMA1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='1' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMA2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='2' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMB1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='3' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMB2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='4' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMC1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='5' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMC2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='6' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMD1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='7' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P1-DIMMD2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='8' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMME1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='9' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMME2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='10' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMF1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='11' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMF1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='12' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMG1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='13' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMG2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='14' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMH1 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ <node instance='15' static='true'>
+ <dependents grouping='children'>
+ <range name='dimm' min='0' max='0'>
+ <node instance='0' static='true'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity-list' type='string_array' >
+ <propitem value='P2-DIMMH2 Temp' />
+ </propval>
+ </propgroup>
+ </node>
+ </range>
+ </dependents>
+ </node>
+
+ </range> <!-- slot -->
+</topology>
diff --git a/usr/src/lib/fm/topo/maps/common/topology.dtd.1 b/usr/src/lib/fm/topo/maps/common/topology.dtd.1
index ae749e6e46..ba474a66b6 100644
--- a/usr/src/lib/fm/topo/maps/common/topology.dtd.1
+++ b/usr/src/lib/fm/topo/maps/common/topology.dtd.1
@@ -3,6 +3,8 @@
Copyright 2009 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
+ Copyright (c) 2018, Joyent, Inc.
+
CDDL HEADER START
The contents of this file are subject to the terms of the
@@ -275,7 +277,8 @@
( fac-enum?, facility*, propgroup*, set*, enum-method*, dependents? ) >
<!ATTLIST node
- instance CDATA #REQUIRED >
+ instance CDATA #REQUIRED
+ static (false|true) "false" >
<!--
dependents
diff --git a/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml b/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml
index 1a459d854b..607f7e1eb1 100644
--- a/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml
+++ b/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml
@@ -2,7 +2,7 @@
<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
<!--
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
-Copyright (c) 2017, Joyent, Inc.
+Copyright (c) 2018, Joyent, Inc.
CDDL HEADER START
@@ -77,9 +77,15 @@ Copyright (c) 2017, Joyent, Inc.
<enum-method name='chip' version='1' />
<propmap name='chip' />
</range>
+ <range name='slot' min='0' max='31'>
+ <enum-method name='smbios' version='1' />
+ </range>
<range name='hostbridge' min='0' max='254'>
<enum-method name='hostbridge' version='1' />
</range>
+ <range name='sp' min='0' max='0'>
+ <enum-method name='ipmi' version='1' />
+ </range>
</dependents>
</range>
diff --git a/usr/src/lib/fm/topo/modules/common/Makefile b/usr/src/lib/fm/topo/modules/common/Makefile
index d725016aef..f7f47f5e06 100644
--- a/usr/src/lib/fm/topo/modules/common/Makefile
+++ b/usr/src/lib/fm/topo/modules/common/Makefile
@@ -22,7 +22,7 @@
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-# Copyright (c) 2017, Joyent, Inc.
+# Copyright (c) 2018, Joyent, Inc.
#
SUBDIRS = \
@@ -32,6 +32,7 @@ SUBDIRS = \
ipmi \
nic \
ses \
+ smbios \
xfp
ses: disk
diff --git a/usr/src/lib/fm/topo/modules/common/ipmi/Makefile b/usr/src/lib/fm/topo/modules/common/ipmi/Makefile
index b6f2839c42..4a0bf39401 100644
--- a/usr/src/lib/fm/topo/modules/common/ipmi/Makefile
+++ b/usr/src/lib/fm/topo/modules/common/ipmi/Makefile
@@ -22,7 +22,8 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
+# Copyright (c) 2018, Joyent, Inc.
+#
MODULE = ipmi
CLASS = common
@@ -31,4 +32,4 @@ MODULESRCS = ipmi_enum.c ipmi_methods.c
include ../../Makefile.plugin
-LDLIBS += -lipmi
+LDLIBS += -lipmi -lnsl
diff --git a/usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c b/usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c
index ef7a2d23ac..1220305584 100644
--- a/usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c
+++ b/usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Joyent, Inc.
+ * Copyright (c) 2018, Joyent, Inc.
*/
#include <assert.h>
@@ -29,6 +29,9 @@
#include <fm/topo_mod.h>
#include <sys/fm/protocol.h>
#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
#define TOPO_PGROUP_IPMI "ipmi"
#define TOPO_PROP_IPMI_ENTITY_REF "entity_ref"
@@ -472,6 +475,260 @@ ipmi_check_entity(ipmi_handle_t *ihp, ipmi_entity_t *ep, void *data)
return (0);
}
+static const char *
+ipmi2toposrc(uint8_t ipmi_ip_src)
+{
+ char *cfgtype;
+
+ switch (ipmi_ip_src) {
+ case (IPMI_LAN_SRC_STATIC):
+ case (IPMI_LAN_SRC_BIOS):
+ cfgtype = TOPO_NETCFG_TYPE_STATIC;
+ break;
+ case (IPMI_LAN_SRC_DHCP):
+ cfgtype = TOPO_NETCFG_TYPE_DHCP;
+ break;
+ default:
+ cfgtype = TOPO_NETCFG_TYPE_UNKNOWN;
+ break;
+ }
+ return (cfgtype);
+}
+
+/*
+ * Channel related IPMI commands reserve 4 bits for the channel number.
+ */
+#define IPMI_MAX_CHANNEL 0xf
+
+static int
+ipmi_enum_sp(topo_mod_t *mod, tnode_t *pnode)
+{
+ ipmi_handle_t *ihp;
+ ipmi_channel_info_t *chinfo;
+ ipmi_lan_config_t lancfg = { 0 };
+ boolean_t found_lan = B_TRUE;
+ char ipv4_addr[INET_ADDRSTRLEN], subnet[INET_ADDRSTRLEN];
+ char gateway[INET_ADDRSTRLEN], macaddr[18];
+ char ipv6_addr[INET6_ADDRSTRLEN];
+ char **ipv6_routes;
+ const char *sp_rev, *ipv4_cfgtype, *ipv6_cfgtype;
+ nvlist_t *auth, *fmri;
+ tnode_t *sp_node;
+ topo_pgroup_info_t pgi;
+ int err, ch, i, ret = -1;
+
+ if ((ihp = topo_mod_ipmi_hold(mod)) == NULL)
+ return (0);
+
+ /*
+ * If we're able to successfully get the service processor version by
+ * issuing a GET_DEVICE_ID IPMI command over the KCS interface, then we
+ * can say with certainty that a service processor exists. If not,
+ * then either the SP is unresponsive or one isn't present. In either
+ * case, we bail.
+ */
+ if ((sp_rev = ipmi_firmware_version(ihp)) == NULL) {
+ topo_mod_dprintf(mod, "failed to query SP");
+ topo_mod_ipmi_rele(mod);
+ return (0);
+ }
+
+ if ((auth = topo_mod_auth(mod, pnode)) == NULL) {
+ topo_mod_dprintf(mod, "topo_mod_auth() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ goto out;
+ }
+ if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION,
+ SP, 0, NULL, auth, NULL, sp_rev, NULL)) == NULL) {
+ nvlist_free(auth);
+ topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ goto out;
+ }
+ nvlist_free(auth);
+
+ if ((sp_node = topo_node_bind(mod, pnode, SP, 0, fmri)) == NULL) {
+ nvlist_free(fmri);
+ topo_mod_dprintf(mod, "topo_node_bind() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ goto out;
+ }
+ nvlist_free(fmri);
+ fmri = NULL;
+
+ if (topo_node_label_set(sp_node, "service-processor", &err) != 0) {
+ topo_mod_dprintf(mod, "failed to set label on %s=%d: %s", SP,
+ 0, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+
+ if (topo_node_fru(pnode, &fmri, NULL, &err) != 0 ||
+ topo_node_fru_set(sp_node, fmri, NULL, &err) != 0) {
+ topo_mod_dprintf(mod, "failed to set FRU on %s=%d: %s", SP, 0,
+ topo_strerror(err));
+ nvlist_free(fmri);
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+ nvlist_free(fmri);
+
+ /*
+ * Iterate through the channels to find the LAN channel.
+ */
+ for (ch = 0; ch <= IPMI_MAX_CHANNEL; ch++) {
+ if ((chinfo = ipmi_get_channel_info(ihp, ch)) != NULL &&
+ chinfo->ici_medium == IPMI_MEDIUM_8023LAN) {
+ found_lan = B_TRUE;
+ break;
+ }
+ }
+ /*
+ * If we found a LAN channel, look up its configuration so that we can
+ * expose it via node properties.
+ */
+ if (found_lan != B_TRUE ||
+ ipmi_lan_get_config(ihp, ch, &lancfg) != 0) {
+ (void) fprintf(stderr, "failed to get LAN config\n");
+ (void) topo_mod_seterrno(mod, EMOD_UNKNOWN);
+ goto out;
+ }
+
+ pgi.tpi_name = TOPO_PGROUP_NETCFG;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = TOPO_VERSION;
+
+ if (topo_pgroup_create(sp_node, &pgi, &err) != 0) {
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+
+ /* Set MAC address property */
+ (void) sprintf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+ lancfg.ilc_macaddr[0], lancfg.ilc_macaddr[1],
+ lancfg.ilc_macaddr[2], lancfg.ilc_macaddr[3],
+ lancfg.ilc_macaddr[4], lancfg.ilc_macaddr[5]);
+ macaddr[17] = '\0';
+
+ if (topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_MACADDR, TOPO_PROP_IMMUTABLE, macaddr,
+ &err) != 0) {
+ topo_mod_dprintf(mod, "failed to set properties on %s=%d: %s",
+ SP, 0, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+
+ /* Set VLAN ID property, if VLAN is enabled */
+ if (lancfg.ilc_vlan_enabled == B_TRUE &&
+ topo_prop_set_uint32(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_VLAN_ID, TOPO_PROP_IMMUTABLE, lancfg.ilc_vlan_id,
+ &err) != 0) {
+ topo_mod_dprintf(mod, "failed to set properties on %s=%d: %s",
+ SP, 0, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+
+ /* Set IPv4 configuration properties if IPv4 is enabled */
+ if (lancfg.ilc_ipv4_enabled == B_TRUE &&
+ (inet_ntop(AF_INET, &lancfg.ilc_ipaddr, ipv4_addr,
+ sizeof (ipv4_addr)) == NULL ||
+ inet_ntop(AF_INET, &lancfg.ilc_subnet, subnet,
+ sizeof (subnet)) == NULL ||
+ inet_ntop(AF_INET, &lancfg.ilc_gateway_addr, gateway,
+ sizeof (gateway)) == NULL)) {
+ (void) fprintf(stderr, "failed to convert IP addresses: %s\n",
+ strerror(errno));
+ (void) topo_mod_seterrno(mod, EMOD_UNKNOWN);
+ goto out;
+ }
+ ipv4_cfgtype = ipmi2toposrc(lancfg.ilc_ipaddr_source);
+ if (lancfg.ilc_ipv4_enabled == B_TRUE &&
+ (topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV4_ADDR, TOPO_PROP_IMMUTABLE, ipv4_addr,
+ &err) != 0 ||
+ topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV4_SUBNET, TOPO_PROP_IMMUTABLE, subnet,
+ &err) != 0 ||
+ topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV4_GATEWAY, TOPO_PROP_IMMUTABLE, gateway,
+ &err) != 0 ||
+ topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV4_TYPE, TOPO_PROP_IMMUTABLE, ipv4_cfgtype,
+ &err) != 0)) {
+ topo_mod_dprintf(mod, "failed to set properties on %s=%d: %s",
+ SP, 0, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+
+ /* Set IPv6 configuration properties if IPv6 is enabled */
+ if (lancfg.ilc_ipv6_enabled == B_TRUE) {
+ ipv6_cfgtype = ipmi2toposrc(lancfg.ilc_ipv6_source);
+
+ if (inet_ntop(AF_INET6, &lancfg.ilc_ipv6_addr, ipv6_addr,
+ sizeof (ipv6_addr)) == NULL) {
+ (void) fprintf(stderr, "failed to convert IPv6 "
+ "address: %s\n", strerror(errno));
+ (void) topo_mod_seterrno(mod, EMOD_UNKNOWN);
+ goto out;
+ }
+
+ /* allocate and populate ipv6-routes string array */
+ if ((ipv6_routes = topo_mod_zalloc(mod,
+ lancfg.ilc_ipv6_nroutes * sizeof (char *))) == NULL) {
+ /* errno set */
+ goto out;
+ }
+ for (i = 0; i < lancfg.ilc_ipv6_nroutes; i++) {
+ if ((ipv6_routes[i] = topo_mod_alloc(mod,
+ INET6_ADDRSTRLEN)) == NULL) {
+ /* errno set */
+ goto out;
+ }
+ }
+ for (i = 0; i < lancfg.ilc_ipv6_nroutes; i++) {
+ if (inet_ntop(AF_INET6, &lancfg.ilc_ipv6_routes[i],
+ ipv6_routes[i], sizeof (ipv6_routes[i])) == NULL) {
+ (void) fprintf(stderr, "failed to convert "
+ "IPv6 addresses: %s\n", strerror(errno));
+ (void) topo_mod_seterrno(mod, EMOD_UNKNOWN);
+ goto out;
+ }
+ }
+ }
+ if (lancfg.ilc_ipv6_enabled == B_TRUE &&
+ (topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV6_ADDR, TOPO_PROP_IMMUTABLE, ipv6_addr,
+ &err) != 0 ||
+ topo_prop_set_string_array(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV6_ROUTES, TOPO_PROP_IMMUTABLE,
+ (const char **)ipv6_routes, lancfg.ilc_ipv6_nroutes, &err) != 0 ||
+ topo_prop_set_string(sp_node, TOPO_PGROUP_NETCFG,
+ TOPO_PROP_NETCFG_IPV6_TYPE, TOPO_PROP_IMMUTABLE, ipv6_cfgtype,
+ &err) != 0)) {
+ topo_mod_dprintf(mod, "failed to set properties on %s=%d: %s",
+ SP, 0, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ goto out;
+ }
+ ret = 0;
+out:
+ if (lancfg.ilc_ipv6_nroutes > 0) {
+ for (i = 0; i < lancfg.ilc_ipv6_nroutes; i++)
+ topo_mod_free(mod, ipv6_routes[i], INET6_ADDRSTRLEN);
+ topo_mod_free(mod, ipv6_routes,
+ lancfg.ilc_ipv6_nroutes * sizeof (char *));
+ }
+ topo_mod_ipmi_rele(mod);
+ return (ret);
+}
+
/*
* libtopo enumeration point. This simply iterates over entities looking for
* the appropriate type.
@@ -486,10 +743,11 @@ ipmi_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
int ret;
/*
- * If the node being passed in ISN'T the chassis node, then we're being
- * asked to post-process a statically defined node.
+ * If the node being passed in ISN'T the chassis or motherboard node,
+ * then we're being asked to post-process a statically defined node.
*/
- if (strcmp(topo_node_name(rnode), CHASSIS) != 0) {
+ if (strcmp(topo_node_name(rnode), CHASSIS) != 0 &&
+ strcmp(topo_node_name(rnode), MOTHERBOARD) != 0) {
if (ipmi_post_process(mod, rnode) != 0) {
topo_mod_dprintf(mod, "post processing of node %s=%d "
"failed!", topo_node_name(rnode),
@@ -499,6 +757,19 @@ ipmi_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
return (0);
}
+ /*
+ * For service processor enumeration we vector off into a special code
+ * path.
+ */
+ if (strcmp(name, SP) == 0) {
+ if (ipmi_enum_sp(mod, rnode) != 0) {
+ topo_mod_dprintf(mod, "failed to enumerate the "
+ "service-processor");
+ return (-1);
+ }
+ return (0);
+ }
+
if (strcmp(name, POWERMODULE) == 0) {
data.ed_entity = IPMI_ET_POWER_DOMAIN;
} else if (strcmp(name, PSU) == 0) {
diff --git a/usr/src/lib/fm/topo/modules/common/smbios/Makefile b/usr/src/lib/fm/topo/modules/common/smbios/Makefile
new file mode 100644
index 0000000000..04590063c5
--- /dev/null
+++ b/usr/src/lib/fm/topo/modules/common/smbios/Makefile
@@ -0,0 +1,22 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2018, Joyent, Inc.
+#
+
+MODULE = smbios
+CLASS = common
+MODULESRCS = smbios_enum.c
+
+include ../../Makefile.plugin
+
+LDLIBS += -lsmbios
diff --git a/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c b/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c
new file mode 100644
index 0000000000..ecaa749bed
--- /dev/null
+++ b/usr/src/lib/fm/topo/modules/common/smbios/smbios_enum.c
@@ -0,0 +1,483 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2018, Joyent, Inc.
+ */
+
+#include <assert.h>
+#include <fcntl.h>
+#include <fm/libtopo.h>
+#include <fm/topo_mod.h>
+#include <sys/mc.h>
+#include <sys/fm/protocol.h>
+#include <string.h>
+#include <unistd.h>
+
+#define TOPO_PGROUP_DIMM_PROPS "dimm-properties"
+
+typedef struct smb_enum_data {
+ topo_mod_t *sme_mod;
+ tnode_t *sme_pnode;
+ tnode_t *sme_slotnode;
+ topo_instance_t sme_slot_inst;
+ topo_instance_t sme_slot_maxinst;
+ smbios_info_t *sme_smb_info;
+ char *sme_slot_form;
+} smb_enum_data_t;
+
+/*
+ * This function serves two purposes. It filters out memory devices that
+ * don't have a formfactor that represents a reasonably modern DIMM-like
+ * device (and hence not a device we're insterested in enumerating). It also
+ * converts the numeric SMBIOS type representation to a more generic TOPO dimm
+ * type.
+ *
+ * Caller must free the returned string.
+ */
+static char *
+distill_dimm_form(topo_mod_t *mod, smbios_memdevice_t *smb_md)
+{
+ switch (smb_md->smbmd_form) {
+ case (SMB_MDFF_DIMM):
+ return (topo_mod_strdup(mod, TOPO_DIMM_SLOT_FORM_DIMM));
+ case (SMB_MDFF_SODIMM):
+ return (topo_mod_strdup(mod, TOPO_DIMM_SLOT_FORM_SODIMM));
+ case (SMB_MDFF_FBDIMM):
+ return (topo_mod_strdup(mod, TOPO_DIMM_SLOT_FORM_FBDIMM));
+ default:
+ topo_mod_dprintf(mod, "skipping device with form factor 0x%x",
+ smb_md->smbmd_form);
+ return (NULL);
+ }
+}
+
+static char *
+smbios2topotype(topo_mod_t *mod, uint8_t type)
+{
+ switch (type) {
+ case (SMB_MDT_DDR):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_DDR));
+ case (SMB_MDT_DDR2):
+ case (SMB_MDT_DDR2FBDIMM):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_DDR2));
+ case (SMB_MDT_DDR3):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_DDR3));
+ case (SMB_MDT_DDR4):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_DDR4));
+ case (SMB_MDT_LPDDR):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_LPDDR));
+ case (SMB_MDT_LPDDR2):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_LPDDR2));
+ case (SMB_MDT_LPDDR3):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_LPDDR3));
+ case (SMB_MDT_LPDDR4):
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_LPDDR4));
+ default:
+ return (topo_mod_strdup(mod, TOPO_DIMM_TYPE_UNKNOWN));
+ }
+}
+
+static boolean_t
+is_valid_string(const char *str)
+{
+ if (strcmp(str, SMB_DEFAULT1) != 0 && strcmp(str, SMB_DEFAULT2) != 0 &&
+ strlen(str) > 0)
+ return (B_TRUE);
+
+ return (B_FALSE);
+}
+
+static tnode_t *
+smbios_make_slot(smb_enum_data_t *smed, smbios_memdevice_t *smb_md)
+{
+ nvlist_t *auth, *fmri;
+ tnode_t *slotnode;
+ topo_mod_t *mod = smed->sme_mod;
+ topo_pgroup_info_t pgi;
+ int err;
+
+ if ((auth = topo_mod_auth(mod, smed->sme_pnode)) == NULL) {
+ topo_mod_dprintf(mod, "topo_mod_auth() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ return (NULL);
+ }
+
+ if ((fmri = topo_mod_hcfmri(mod, smed->sme_pnode, FM_HC_SCHEME_VERSION,
+ SLOT, smed->sme_slot_inst, NULL, auth, NULL, NULL, NULL)) ==
+ NULL) {
+ nvlist_free(auth);
+ topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ return (NULL);
+ }
+ nvlist_free(auth);
+ if ((slotnode = topo_node_bind(mod, smed->sme_pnode, SLOT,
+ smed->sme_slot_inst, fmri)) == NULL) {
+ nvlist_free(fmri);
+ topo_mod_dprintf(mod, "topo_node_bind() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ return (NULL);
+ }
+ nvlist_free(fmri);
+ fmri = NULL;
+
+ if (topo_node_label_set(slotnode, (char *)smb_md->smbmd_dloc, &err) !=
+ 0) {
+ topo_mod_dprintf(mod, "failed to set label on %s=%d: %s",
+ SLOT, smed->sme_slot_inst, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ return (NULL);
+ }
+ if (topo_node_fru(smed->sme_pnode, &fmri, NULL, &err) != 0 ||
+ topo_node_fru_set(slotnode, fmri, NULL, &err) != 0) {
+ topo_mod_dprintf(mod, "failed to set FRU on %s=%d: %s", SLOT,
+ smed->sme_slot_inst, topo_strerror(err));
+ nvlist_free(fmri);
+ (void) topo_mod_seterrno(mod, err);
+ return (NULL);
+ }
+ nvlist_free(fmri);
+
+ pgi.tpi_name = TOPO_PGROUP_SLOT;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = TOPO_VERSION;
+ if (topo_pgroup_create(slotnode, &pgi, &err) != 0 ||
+ topo_prop_set_uint32(slotnode, TOPO_PGROUP_SLOT,
+ TOPO_PROP_SLOT_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SLOT_TYPE_DIMM,
+ &err)) {
+ topo_mod_dprintf(mod, "failed to create slot properties: %s",
+ topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ return (NULL);
+ }
+
+ pgi.tpi_name = TOPO_PGROUP_DIMM_SLOT;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = TOPO_VERSION;
+ if (topo_pgroup_create(slotnode, &pgi, &err) != 0 ||
+ topo_prop_set_string(slotnode, TOPO_PGROUP_DIMM_SLOT,
+ TOPO_PROP_DIMM_SLOT_FORM, TOPO_PROP_IMMUTABLE, smed->sme_slot_form,
+ &err)) {
+ topo_mod_dprintf(mod, "failed to create slot properties: %s",
+ topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ return (NULL);
+ }
+ return (slotnode);
+}
+
+static tnode_t *
+smbios_make_dimm(smb_enum_data_t *smed, smbios_memdevice_t *smb_md)
+{
+ nvlist_t *auth, *fmri;
+ smbios_info_t *smb_info = smed->sme_smb_info;
+ tnode_t *slotnode = smed->sme_slotnode;
+ tnode_t *dimmnode, *ret = NULL;
+ topo_mod_t *mod = smed->sme_mod;
+ topo_pgroup_info_t pgi;
+ const char *part = NULL, *rev = NULL, *serial = NULL;
+ char *type, *manuf = NULL, *prod = NULL, *asset = NULL, *loc = NULL;
+ int err, rc = 0;
+
+ if ((auth = topo_mod_auth(mod, slotnode)) == NULL) {
+ topo_mod_dprintf(mod, "topo_mod_auth() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ return (NULL);
+ }
+
+ if (smed->sme_smb_info != NULL) {
+ if (is_valid_string(smb_info->smbi_part) == B_TRUE)
+ part = smb_info->smbi_part;
+ if (is_valid_string(smb_info->smbi_version) == B_TRUE)
+ rev = smb_info->smbi_version;
+ if (is_valid_string(smb_info->smbi_serial) == B_TRUE)
+ serial = smb_info->smbi_serial;
+ if (is_valid_string(smb_info->smbi_manufacturer) == B_TRUE)
+ manuf = topo_mod_clean_str(mod,
+ smb_info->smbi_manufacturer);
+ if (is_valid_string(smb_info->smbi_product) == B_TRUE)
+ prod = topo_mod_clean_str(mod, smb_info->smbi_product);
+ if (is_valid_string(smb_info->smbi_asset) == B_TRUE)
+ asset = topo_mod_clean_str(mod, smb_info->smbi_asset);
+ if (is_valid_string(smb_info->smbi_location) == B_TRUE)
+ loc = topo_mod_clean_str(mod, smb_info->smbi_location);
+ }
+
+ if ((fmri = topo_mod_hcfmri(mod, slotnode, FM_HC_SCHEME_VERSION,
+ DIMM, 0, NULL, auth, part, rev, serial)) == NULL) {
+ nvlist_free(auth);
+ topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ goto err;
+ }
+ nvlist_free(auth);
+
+ if (topo_node_range_create(mod, slotnode, DIMM, 0, 0) < 0 ||
+ (dimmnode = topo_node_bind(mod, slotnode, DIMM, 0, fmri)) ==
+ NULL) {
+ nvlist_free(fmri);
+ topo_mod_dprintf(mod, "failed to bind dimm node: %s",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ goto err;
+ }
+
+ if (topo_node_fru_set(dimmnode, fmri, NULL, &err) != 0) {
+ topo_mod_dprintf(mod, "failed to set FRU on %s: %s",
+ DIMM, topo_strerror(err));
+ nvlist_free(fmri);
+ (void) topo_mod_seterrno(mod, err);
+ goto err;
+ }
+ nvlist_free(fmri);
+
+ if (topo_node_label_set(dimmnode, (char *)smb_md->smbmd_dloc, &err) !=
+ 0) {
+ topo_mod_dprintf(mod, "failed to set label on %s: %s",
+ DIMM, topo_strerror(err));
+ (void) topo_mod_seterrno(mod, err);
+ goto err;
+ }
+
+ pgi.tpi_name = TOPO_PGROUP_DIMM_PROPS;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = TOPO_VERSION;
+ if (topo_pgroup_create(dimmnode, &pgi, &err) != 0) {
+ (void) topo_mod_seterrno(mod, err);
+ goto err;
+ }
+
+ rc += topo_prop_set_uint64(dimmnode, TOPO_PGROUP_DIMM_PROPS, "size",
+ TOPO_PROP_IMMUTABLE, smb_md->smbmd_size, &err);
+ if (rc == 0 && (type = smbios2topotype(mod, smb_md->smbmd_type)) !=
+ NULL) {
+ rc += topo_prop_set_string(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "type", TOPO_PROP_IMMUTABLE, type, &err);
+ topo_mod_strfree(mod, type);
+ }
+ if (rc == 0 && smb_md->smbmd_set != 0 && smb_md->smbmd_set != 0xFF)
+ rc += topo_prop_set_uint32(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "set", TOPO_PROP_IMMUTABLE, smb_md->smbmd_set, &err);
+ if (rc == 0 && smb_md->smbmd_rank != 0)
+ rc += topo_prop_set_uint32(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "rank", TOPO_PROP_IMMUTABLE, smb_md->smbmd_rank, &err);
+ if (rc == 0 && smb_md->smbmd_clkspeed != 0)
+ rc += topo_prop_set_uint32(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "configured-speed", TOPO_PROP_IMMUTABLE,
+ smb_md->smbmd_clkspeed, &err);
+ if (rc == 0 && smb_md->smbmd_speed != 0)
+ rc += topo_prop_set_uint32(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "maximum-speed", TOPO_PROP_IMMUTABLE, smb_md->smbmd_speed,
+ &err);
+ if (rc == 0 && smb_md->smbmd_maxvolt != 0)
+ rc += topo_prop_set_double(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "maximum-voltage", TOPO_PROP_IMMUTABLE,
+ (smb_md->smbmd_maxvolt / 1000), &err);
+ if (rc == 0 && smb_md->smbmd_minvolt != 0)
+ rc += topo_prop_set_double(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "minimum-voltage", TOPO_PROP_IMMUTABLE,
+ (smb_md->smbmd_minvolt / 1000), &err);
+ if (rc == 0 && smb_md->smbmd_confvolt != 0)
+ rc += topo_prop_set_double(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "configured-voltage", TOPO_PROP_IMMUTABLE,
+ (smb_md->smbmd_confvolt / 1000), &err);
+ if (rc == 0 && manuf != NULL)
+ rc += topo_prop_set_string(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "manufacturer", TOPO_PROP_IMMUTABLE, manuf, &err);
+ if (rc == 0 && prod != NULL)
+ rc += topo_prop_set_string(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "product", TOPO_PROP_IMMUTABLE, prod, &err);
+ if (rc == 0 && asset != NULL)
+ rc += topo_prop_set_string(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "asset-tag", TOPO_PROP_IMMUTABLE, asset, &err);
+ if (rc == 0 && loc != NULL)
+ rc += topo_prop_set_string(dimmnode, TOPO_PGROUP_DIMM_PROPS,
+ "location", TOPO_PROP_IMMUTABLE, loc, &err);
+
+ if (rc != 0) {
+ topo_mod_dprintf(mod, "error setting properties on %s node",
+ DIMM);
+ (void) topo_mod_seterrno(mod, err);
+ goto err;
+ }
+ ret = dimmnode;
+err:
+ topo_mod_strfree(mod, manuf);
+ topo_mod_strfree(mod, prod);
+ topo_mod_strfree(mod, asset);
+ topo_mod_strfree(mod, loc);
+ return (ret);
+}
+
+static int
+smbios_enum_memory(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
+{
+ smbios_info_t smb_info;
+ smbios_memdevice_t smb_md;
+ smb_enum_data_t *smed = arg;
+ topo_mod_t *mod = smed->sme_mod;
+ tnode_t *slotnode;
+
+ if (sp->smbstr_type != SMB_TYPE_MEMDEVICE)
+ return (0);
+
+ if (smbios_info_memdevice(shp, sp->smbstr_id, &smb_md) != 0) {
+ topo_mod_dprintf(mod, "libsmbios error");
+ return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
+ }
+
+ /*
+ * SMB_TYPE_MEMDEVICE records can also be used to represent memory
+ * that come in non-DIMM form factors. If we encounter something like
+ * that, then we skip over it.
+ */
+ if ((smed->sme_slot_form = distill_dimm_form(mod, &smb_md)) == NULL)
+ return (0);
+
+ if ((slotnode = smbios_make_slot(smed, &smb_md)) == NULL) {
+ topo_mod_dprintf(mod, "failed to create %s node", SLOT);
+ topo_mod_strfree(mod, smed->sme_slot_form);
+ /* errno set */
+ return (-1);
+ }
+ topo_mod_strfree(mod, smed->sme_slot_form);
+ smed->sme_slotnode = slotnode;
+
+ /*
+ * A size of zero indicates that the DIMM slot is not populated, so
+ * we skip creating a child dimm node and return.
+ */
+ if (smb_md.smbmd_size == 0) {
+ smed->sme_slot_inst++;
+ return (0);
+ }
+
+ if (smbios_info_common(shp, sp->smbstr_id, &smb_info) == 0)
+ smed->sme_smb_info = &smb_info;
+
+ if (smbios_make_dimm(smed, &smb_md) == NULL) {
+ topo_mod_dprintf(mod, "failed to create %s node", DIMM);
+ /* errno set */
+ return (-1);
+ }
+ /*
+ * If we've exceeded our max inst then return non-zero to cause
+ * the walk to terminate.
+ */
+ if (++smed->sme_slot_inst > smed->sme_slot_maxinst)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * A system with a functional memory controller driver will have one mc device
+ * node per chip instance, starting at instance 0. The driver provides an
+ * ioctl interface for retrieving a snapshot of the system's memory topology.
+ * If we're able to issue this ioctl on one of the mc device nodes then we'll
+ * return B_TRUE, indicating that this system has a minimally functional memory
+ * controller driver.
+ */
+static boolean_t
+has_mc_driver()
+{
+ int mc_fd;
+ mc_snapshot_info_t mcs;
+
+ if ((mc_fd = open("/dev/mc/mc0", O_RDONLY)) < 0)
+ return (B_FALSE);
+
+ if (ioctl(mc_fd, MC_IOC_SNAPSHOT_INFO, &mcs) < 0) {
+ (void) close(mc_fd);
+ return (B_FALSE);
+ }
+ (void) close(mc_fd);
+ return (B_TRUE);
+}
+
+/*ARGSUSED*/
+static int
+smbios_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+ topo_instance_t min, topo_instance_t max, void *arg, void *unused)
+{
+ smbios_hdl_t *smbh;
+ smb_enum_data_t smed = { 0 };
+
+ if ((smbh = topo_mod_smbios(mod)) == NULL) {
+ topo_mod_dprintf(mod, "failed to get libsmbios handle");
+ return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
+ }
+ smed.sme_mod = mod;
+ smed.sme_pnode = rnode;
+ smed.sme_slot_inst = min;
+ smed.sme_slot_maxinst = max;
+
+ /*
+ * Currently we only support enumerating dimm-slot and dimm nodes, but
+ * this module could be expanded in the future to enumerate other
+ * hardware components from SMBIOS.
+ */
+ if (strcmp(name, SLOT) == 0) {
+ /*
+ * If the system has a functional memory controller driver then
+ * we'll assume that it has responsibility for enumerating the
+ * memory topology.
+ */
+ if (has_mc_driver() == B_TRUE)
+ return (0);
+ if (smbios_iter(smbh, smbios_enum_memory, &smed) < 0)
+ /* errno set */
+ return (-1);
+ } else {
+ topo_mod_dprintf(mod, "smbios_enum() invoked for unsupported "
+ "node type: %s", name);
+ return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
+ }
+ return (0);
+}
+
+const topo_modops_t smbios_ops = { smbios_enum, NULL };
+
+const topo_modinfo_t smbios_info =
+ { "smbios", FM_FMRI_SCHEME_HC, TOPO_VERSION, &smbios_ops };
+
+/*ARGSUSED*/
+int
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+ if (getenv("TOPOSMBIOSDEBUG") != NULL)
+ topo_mod_setdebug(mod);
+
+ if (topo_mod_register(mod, &smbios_info, TOPO_VERSION) != 0) {
+ topo_mod_dprintf(mod, "module registration failed: %s\n",
+ topo_mod_errmsg(mod));
+ /* errno set */
+ return (-1);
+ }
+
+ topo_mod_dprintf(mod, "SMBIOS enumerator initialized\n");
+ return (0);
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+ topo_mod_unregister(mod);
+}
diff --git a/usr/src/lib/libipmi/common/ipmi_lancfg.c b/usr/src/lib/libipmi/common/ipmi_lancfg.c
index 3e3ebc6e81..b324891e3f 100644
--- a/usr/src/lib/libipmi/common/ipmi_lancfg.c
+++ b/usr/src/lib/libipmi/common/ipmi_lancfg.c
@@ -22,6 +22,9 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2018, Joyent, Inc.
+ */
/*
* Query and configure LAN interfaces over IPMI. This is done through the
@@ -34,6 +37,7 @@
#include <strings.h>
#include <libipmi.h>
+#include <netinet/in.h>
#include "ipmi_impl.h"
@@ -65,10 +69,26 @@ typedef struct ipmi_cmd_lan_set_config {
#define IPMI_LAN_PARAM_SUBNET_MASK 6
#define IPMI_LAN_PARAM_GATEWAY_ADDR 12
+/* VLAN/IPv6 parameters are currently only supported for GET operations */
+#define IPMI_LAN_PARAM_VLAN_ID 20
+#define IPMI_LAN_PARAM_IPVX_ENABLED 51
+#define IPMI_LAN_PARAM_IPV6_NUM_ADDRS 55
+#define IPMI_LAN_PARAM_IPV6_SADDR 56
+#define IPMI_LAN_PARAM_IPV6_DADDR 59
+#define IPMI_LAN_PARAM_IPV6_ROUTER_CONFIG 64
+#define IPMI_LAN_PARAM_IPV6_STATIC_ROUTE1 65
+#define IPMI_LAN_PARAM_IPV6_STATIC_ROUTE2 68
+#define IPMI_LAN_PARAM_IPV6_NUM_DYN_ROUTES 72
+#define IPMI_LAN_PARAM_IPV6_DYN_ROUTE 73
+
#define IPMI_LAN_SET_COMPLETE 0x0
#define IPMI_LAN_SET_INPROGRESS 0x1
#define IPMI_LAN_SET_COMMIT 0x2
+/* bitfield values of IPMI_LAN_PARAM_IPV6_ROUTER_CONFIG param */
+#define IPMI_LAN_IPV6_STATIC_ROUTES_ENABLED 0x1
+#define IPMI_LAN_IPV6_DYNAMIC_ROUTES_ENABLED 0x2
+
typedef struct ipmi_lan_entry {
int ile_param;
int ile_mask;
@@ -78,7 +98,7 @@ typedef struct ipmi_lan_entry {
size_t ile_len;
} ipmi_lan_entry_t;
-static ipmi_lan_entry_t ipmi_lan_table[] = {
+static ipmi_lan_entry_t ipmi_lan_ipv4_table[] = {
{ IPMI_LAN_PARAM_IP_ADDR, IPMI_LAN_SET_IPADDR, 0, 0,
offsetof(ipmi_lan_config_t, ilc_ipaddr), sizeof (uint32_t) },
{ IPMI_LAN_PARAM_IP_SOURCE, IPMI_LAN_SET_IPADDR_SOURCE, 0, 0,
@@ -91,8 +111,8 @@ static ipmi_lan_entry_t ipmi_lan_table[] = {
offsetof(ipmi_lan_config_t, ilc_gateway_addr), sizeof (uint32_t) }
};
-#define IPMI_LAN_NENTRIES \
- (sizeof (ipmi_lan_table) / sizeof (ipmi_lan_table[0]))
+#define IPMI_LAN_IPV4_NENTRIES \
+ (sizeof (ipmi_lan_ipv4_table) / sizeof (ipmi_lan_ipv4_table[0]))
static int
ipmi_lan_get_param(ipmi_handle_t *ihp, int channel, int param, int set,
@@ -129,15 +149,44 @@ ipmi_lan_get_param(ipmi_handle_t *ihp, int channel, int param, int set,
return (0);
}
+struct ipmi_lan_ipv6_addr {
+ uint8_t ipva_selector;
+ uint8_t ipva_source;
+ uint8_t ipva_addr[16];
+ uint8_t ipva_prefixlen;
+ uint8_t ipva_status;
+};
+
+struct ipmi_lan_ipv6_numaddrs {
+ uint8_t inva_num_saddrs;
+ uint8_t inva_num_daddrs;
+ uint8_t inva_support;
+};
+
+struct ipmi_lan_vlan_cfg {
+ uint8_t ivla_vlanid_lower;
+ DECL_BITFIELD3(
+ ivla_vlanid_upper :4,
+ __reserved :3,
+ ivla_vlan_enable :1);
+};
+
int
ipmi_lan_get_config(ipmi_handle_t *ihp, int channel, ipmi_lan_config_t *cfgp)
{
- uint8_t set;
- int i;
+ uint8_t set, enabled, route_cfg, ndynroutes = 0;
+ int i, j;
ipmi_lan_entry_t *lep;
+ struct ipmi_lan_ipv6_numaddrs numaddrs = { 0 };
+ struct ipmi_lan_ipv6_addr addrv6 = { 0 };
+ struct ipmi_lan_vlan_cfg vlancfg = { 0 };
+ struct in6_addr sroute1 = { 0 }, sroute2 = { 0 }, droute = { 0 };
+ boolean_t found_addr = B_FALSE;
+ boolean_t stat_routes_enabled = B_FALSE, dyn_routes_enabled = B_FALSE;
if (ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_SET_IN_PROGRESS, 0,
0, &set, sizeof (set)) != 0)
+ /* errno set */
return (-1);
if (set & IPMI_LAN_SET_INPROGRESS)
@@ -145,14 +194,186 @@ ipmi_lan_get_config(ipmi_handle_t *ihp, int channel, ipmi_lan_config_t *cfgp)
else
cfgp->ilc_set_in_progress = B_FALSE;
- for (i = 0; i < IPMI_LAN_NENTRIES; i++) {
- lep = &ipmi_lan_table[i];
- if (ipmi_lan_get_param(ihp, channel, lep->ile_param,
- lep->ile_set, lep->ile_block,
- (char *)cfgp + lep->ile_offset, lep->ile_len) != 0)
+ /*
+ * First determine which IP addressing modes (IPv4/6) are enabled. On
+ * service processors that don't support a version of IPMI that is
+ * IPv6-aware, this parameter won't exist. If we fail to look it up
+ * then we'll assume that only IPv4 is enabled.
+ */
+ if (ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_IPVX_ENABLED, 0, 0,
+ &enabled, sizeof (enabled)) != 0) {
+ cfgp->ilc_ipv4_enabled = B_TRUE;
+ cfgp->ilc_ipv6_enabled = B_FALSE;
+ } else {
+ switch (enabled) {
+ case 0:
+ cfgp->ilc_ipv4_enabled = B_TRUE;
+ cfgp->ilc_ipv6_enabled = B_FALSE;
+ break;
+ case 1:
+ cfgp->ilc_ipv4_enabled = B_FALSE;
+ cfgp->ilc_ipv6_enabled = B_TRUE;
+ break;
+ case 2:
+ cfgp->ilc_ipv4_enabled = B_TRUE;
+ cfgp->ilc_ipv6_enabled = B_TRUE;
+ break;
+ default:
+ return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE, NULL));
+ }
+ }
+
+ /* If IPv4 support is enabled, gather the current configuration. */
+ if (cfgp->ilc_ipv4_enabled == B_TRUE) {
+ for (i = 0; i < IPMI_LAN_IPV4_NENTRIES; i++) {
+ lep = &ipmi_lan_ipv4_table[i];
+ if (ipmi_lan_get_param(ihp, channel, lep->ile_param,
+ lep->ile_set, lep->ile_block,
+ (char *)cfgp + lep->ile_offset, lep->ile_len) != 0)
+ /* errno set */
+ return (-1);
+ }
+ }
+
+ /* Next check if VLAN is enabled, and if so, grab the VLAN ID. */
+ if (ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_VLAN_ID, 0,
+ 0, &vlancfg, sizeof (struct ipmi_lan_vlan_cfg)) != 0) {
+ /* errno set */
+ return (-1);
+ }
+ cfgp->ilc_vlan_enabled = vlancfg.ivla_vlan_enable;
+ if (cfgp->ilc_vlan_enabled == B_TRUE) {
+ cfgp->ilc_vlan_id = (vlancfg.ivla_vlanid_upper << 8) |
+ vlancfg.ivla_vlanid_lower;
+ }
+
+ /* If IPv6 support isn't enabled, then we're all done here. */
+ if (cfgp->ilc_ipv6_enabled != B_TRUE)
+ return (0);
+
+ /*
+ * First check for a static address. If we can't find one, we'll look
+ * for a dynamic address. The spec allows for multiple IPv6 static and
+ * dynamic addresses to exist in various states. For simplicity, we
+ * will search for the first address that is configured and active.
+ */
+ if (ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_IPV6_NUM_ADDRS, 0,
+ 0, &numaddrs, sizeof (numaddrs)) != 0) {
+ /* errno set */
+ return (-1);
+ }
+
+ for (i = 0; i < numaddrs.inva_num_saddrs; i++) {
+ if (ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_IPV6_SADDR,
+ i, 0, &addrv6, sizeof (addrv6)) == 0 &&
+ addrv6.ipva_status == 0) {
+ found_addr = B_TRUE;
+ cfgp->ilc_ipv6_source = IPMI_LAN_SRC_STATIC;
+ break;
+ }
+ }
+ for (i = 0; found_addr == B_FALSE && i < numaddrs.inva_num_daddrs;
+ i++) {
+ if (ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_IPV6_DADDR,
+ i, 0, &addrv6, sizeof (addrv6)) == 0 &&
+ addrv6.ipva_status == 0) {
+ found_addr = B_TRUE;
+ cfgp->ilc_ipv6_source = IPMI_LAN_SRC_DHCP;
+ break;
+ }
+ }
+
+ /*
+ * If we didn't find any active static or dynamic addresses, then
+ * while IPv6 support is enabled, no IPv6 interfaces have been
+ * configured. We reset ilc_ipv6_enabled back to false so that
+ * callers know that the other ilc_ipv6_* fields are not valid.
+ */
+ if (found_addr != B_TRUE) {
+ cfgp->ilc_ipv6_enabled = B_FALSE;
+ return (0);
+ }
+
+ (void) memcpy(cfgp->ilc_ipv6_addr, addrv6.ipva_addr,
+ sizeof (addrv6.ipva_addr));
+
+ /*
+ * For the case that static addressing was used for the SP IP then we
+ * need to get the IPMI_LAN_PARAM_IPV6_ROUTER_CONFIG parameter to
+ * determine if static or dynamic routes are enabled (or both).
+ *
+ * If DHCP was used to assign the SP IP, then only dynamic route
+ * discovery is supported.
+ */
+ if (cfgp->ilc_ipv6_source == IPMI_LAN_SRC_STATIC &&
+ ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_IPV6_ROUTER_CONFIG,
+ 0, 0, &route_cfg, sizeof (route_cfg)) != 0) {
+ /* errno set */
+ return (-1);
+ }
+
+ if (cfgp->ilc_ipv6_source == IPMI_LAN_SRC_STATIC) {
+ if (route_cfg & IPMI_LAN_IPV6_STATIC_ROUTES_ENABLED)
+ stat_routes_enabled = B_TRUE;
+ if (route_cfg & IPMI_LAN_IPV6_DYNAMIC_ROUTES_ENABLED)
+ dyn_routes_enabled = B_TRUE;
+ } else {
+ dyn_routes_enabled = B_TRUE;
+ }
+
+ /*
+ * The IPMI spec allows for a max of two static IPv6 routes to be
+ * configured.
+ */
+ j = cfgp->ilc_ipv6_nroutes = 0;
+ if (stat_routes_enabled == B_TRUE) {
+ cfgp->ilc_ipv6_nroutes = 2;
+ if (ipmi_lan_get_param(ihp, channel,
+ IPMI_LAN_PARAM_IPV6_STATIC_ROUTE1, 0, 0, &sroute1,
+ sizeof (sroute1)) != 0 ||
+ ipmi_lan_get_param(ihp, channel,
+ IPMI_LAN_PARAM_IPV6_STATIC_ROUTE2, 0, 0, &sroute1,
+ sizeof (sroute2)) != 0) {
+ /* errno set */
return (-1);
+ }
+ if (IN6_IS_ADDR_UNSPECIFIED(&sroute1)) {
+ cfgp->ilc_ipv6_nroutes++;
+ (void) memcpy(cfgp->ilc_ipv6_routes[j++], &sroute1,
+ sizeof (sroute1));
+ }
+ if (IN6_IS_ADDR_UNSPECIFIED(&sroute2) != B_TRUE) {
+ cfgp->ilc_ipv6_nroutes++;
+ (void) memcpy(cfgp->ilc_ipv6_routes[j++], &sroute2,
+ sizeof (sroute2));
+ }
}
+ /*
+ * RFC4861 states that if dynamic routing is used, a host should retain
+ * a minimum of two routes, though more is recommended. Retrieve the
+ * number of dynamic routes and then iterate through them and gather
+ * up to the first two addresses.
+ */
+ if (dyn_routes_enabled == B_TRUE &&
+ ipmi_lan_get_param(ihp, channel, IPMI_LAN_PARAM_IPV6_NUM_DYN_ROUTES,
+ 0, 0, &ndynroutes, sizeof (ndynroutes)) != 0) {
+ /* errno set */
+ return (-1);
+ }
+ for (i = 0; i < ndynroutes && i < 2; i++) {
+ if (ipmi_lan_get_param(ihp, channel,
+ IPMI_LAN_PARAM_IPV6_DYN_ROUTE, i, 0, &droute,
+ sizeof (droute)) != 0)
+ /* errno set */
+ return (-1);
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&droute) != B_TRUE) {
+ (void) memcpy(cfgp->ilc_ipv6_routes[j++], &droute,
+ sizeof (droute));
+ cfgp->ilc_ipv6_nroutes++;
+ }
+ }
return (0);
}
@@ -220,8 +441,8 @@ ipmi_lan_set_config(ipmi_handle_t *ihp, int channel, ipmi_lan_config_t *cfgp,
/*
* Iterate over all parameters and set them.
*/
- for (i = 0; i < IPMI_LAN_NENTRIES; i++) {
- lep = &ipmi_lan_table[i];
+ for (i = 0; i < IPMI_LAN_IPV4_NENTRIES; i++) {
+ lep = &ipmi_lan_ipv4_table[i];
if (!(lep->ile_mask & mask))
continue;
diff --git a/usr/src/lib/libipmi/common/libipmi.h b/usr/src/lib/libipmi/common/libipmi.h
index 8552585405..01bf3cb546 100644
--- a/usr/src/lib/libipmi/common/libipmi.h
+++ b/usr/src/lib/libipmi/common/libipmi.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBIPMI_H
@@ -297,6 +297,9 @@ extern ipmi_channel_info_t *ipmi_get_channel_info(ipmi_handle_t *, int);
* This can be expanded in the future as needed.
*/
+/* We'll return up to a maximum of two static routee + two dynamic routes */
+#define IPMI_LAN_IPV6_MAX_ROUTES 4
+
typedef struct ipmi_lan_config {
boolean_t ilc_set_in_progress;
uint32_t ilc_ipaddr;
@@ -304,8 +307,17 @@ typedef struct ipmi_lan_config {
uint8_t ilc_macaddr[6];
uint32_t ilc_subnet;
uint32_t ilc_gateway_addr;
+ uint8_t ilc_ipv6_source;
+ uint8_t ilc_ipv6_addr[16];
+ uint8_t ilc_ipv6_routes[IPMI_LAN_IPV6_MAX_ROUTES][16];
+ uint8_t ilc_ipv6_nroutes;
+ uint16_t ilc_vlan_id;
+ boolean_t ilc_ipv4_enabled;
+ boolean_t ilc_ipv6_enabled;
+ boolean_t ilc_vlan_enabled;
} ipmi_lan_config_t;
+/* values for ilc_ipaddr_source */
#define IPMI_LAN_SRC_UNSPECIFIED 0x0
#define IPMI_LAN_SRC_STATIC 0x1
#define IPMI_LAN_SRC_DHCP 0x2
diff --git a/usr/src/pkg/manifests/service-fault-management.mf b/usr/src/pkg/manifests/service-fault-management.mf
index 0198121c53..4bd1aebf44 100644
--- a/usr/src/pkg/manifests/service-fault-management.mf
+++ b/usr/src/pkg/manifests/service-fault-management.mf
@@ -21,7 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright (c) 2017, Joyent, Inc.
+# Copyright (c) 2018, Joyent, Inc.
#
#
@@ -571,6 +571,7 @@ file path=usr/lib/fm/topo/plugins/fac_prov_mptsas.so mode=0555
file path=usr/lib/fm/topo/plugins/ipmi.so mode=0555
file path=usr/lib/fm/topo/plugins/nic.so mode=0555
file path=usr/lib/fm/topo/plugins/ses.so mode=0555
+file path=usr/lib/fm/topo/plugins/smbios.so mode=0555
file path=usr/lib/fm/topo/plugins/xfp.so mode=0555
#
# Dictionaries, whether they are hardware-specific or not, are
@@ -730,14 +731,23 @@ $(i386_ONLY)file path=usr/platform/i86pc/lib/fm/eft/gcpu.eft mode=0444
$(i386_ONLY)file path=usr/platform/i86pc/lib/fm/eft/gcpu_amd.eft mode=0444
$(i386_ONLY)file path=usr/platform/i86pc/lib/fm/eft/intel.eft mode=0444
$(i386_ONLY)file \
+ path=usr/platform/i86pc/lib/fm/topo/maps/Joyent-Storage-Platform-7001-hc-topology.xml \
+ mode=0444
+$(i386_ONLY)file \
+ path=usr/platform/i86pc/lib/fm/topo/maps/Joyent-Storage-Platform-7001-chassis-hc-topology.xml \
+ mode=0444
+$(i386_ONLY)file \
+ path=usr/platform/i86pc/lib/fm/topo/maps/Joyent-Storage-Platform-7001-slot-hc-topology.xml \
+ mode=0444
+$(i386_ONLY)file \
path=usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-hc-topology.xml \
mode=0444
$(i386_ONLY)link \
path=usr/platform/i86pc/lib/fm/topo/maps/Joyent-Compute-Platform-3101-hc-topology.xml \
- target=./SSG-2028R-ACR24L-hc-topology.xml
+ target=./SSG-2028R-ACR24L-hc-topology.xml
$(i386_ONLY)link \
path=usr/platform/i86pc/lib/fm/topo/maps/Joyent-Compute-Platform-3102-hc-topology.xml \
- target=./SSG-2028R-ACR24L-hc-topology.xml
+ target=./SSG-2028R-ACR24L-hc-topology.xml
$(i386_ONLY)file \
path=usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-chassis-hc-topology.xml \
mode=0444
@@ -745,6 +755,9 @@ $(i386_ONLY)file \
path=usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-disk-hc-topology.xml \
mode=0444
$(i386_ONLY)file \
+ path=usr/platform/i86pc/lib/fm/topo/maps/SSG-2028R-ACR24L-slot-hc-topology.xml \
+ mode=0444
+$(i386_ONLY)file \
path=usr/platform/i86pc/lib/fm/topo/maps/Netra-X4200-M2-disk-hc-topology.xml \
mode=0444
$(i386_ONLY)file \