Jordan Hargrave
2015-08-17 20:46:33 UTC
Some time ago I proposed a patch to enable enabling/disabling individual PEF policy entries.
Support for this is needed for one of our utilities. A new rework of the whole PEF framework was
requested. I'm attaching a patch that (partially) implements this new scheme, please review.
http://sourceforge.net/p/ipmitool/bugs/312/
diff --git a/include/ipmitool/ipmi_mc.h b/include/ipmitool/ipmi_mc.h
index a840f78..fbd2c97 100644
--- a/include/ipmitool/ipmi_mc.h
+++ b/include/ipmitool/ipmi_mc.h
@@ -165,6 +165,8 @@ struct ipm_get_watchdog_rsp {
#define IPMI_SYSINFO_OS_NAME 0x04
#define IPMI_SYSINFO_DELL_OS_VERSION 0xe4
#define IPMI_SYSINFO_DELL_URL 0xde
+#define IPMI_SYSINFO_DELL_IPV6_COUNT 0xe6
+#define IPMI_SYSINFO_DELL_IPV6_DESTADDR 0xf0
int ipmi_mc_getsysinfo(struct ipmi_intf * intf, int param, int block, int set,
int len, void *buffer);
diff --git a/lib/ipmi_pef.c b/lib/ipmi_pef.c
index 1beebf0..fd52663 100644
--- a/lib/ipmi_pef.c
+++ b/lib/ipmi_pef.c
@@ -38,6 +38,7 @@
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_pef.h>
@@ -206,7 +207,7 @@ ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt)
static uint8_t
ipmi_pef_get_policy_table(struct ipmi_intf * intf,
- struct pef_cfgparm_policy_table_entry ** table)
+ struct pef_cfgparm_policy_table_entry ** table)
{ /*
// get the PEF policy table: allocate space, fillin, and return its size
// NB: the caller must free the returned area (when returned size> 0)
@@ -257,6 +258,53 @@ ipmi_pef_get_policy_table(struct ipmi_intf * intf,
}
static void
+ipmi_pef_print_oem_lan_dest(struct ipmi_intf *intf, uint8_t ch, uint8_t dest)
+{
+ int rc, i;
+ uint8_t data[32];
+ char address[128];
+ int len, set, rlen;
+
+ if (ipmi_get_oem(intf) != IPMI_OEM_DELL) {
+ return;
+ }
+ /* Get # of IPV6 trap destinations */
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_COUNT, 0x00, 0x00, 4, data);
+ if (rc != 0 || dest> data[0]) {
+ return;
+ }
+ ipmi_pef_print_str("Alert destination type", "xxx");
+ ipmi_pef_print_str("PET Community", "xxx");
+ ipmi_pef_print_dec("ACK timeout/retry (secs)", 0);
+ ipmi_pef_print_dec("Retries", 0);
+
+ /* Get IPv6 destination string (may be in multiple sets) */
+ memset(address, 0, sizeof(address));
+ memset(data, 0, sizeof(data));
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, 0x00, dest, 19, data);
+ if (rc != 0) {
+ return;
+ }
+ /* Total length of IPv6 string */
+ len = data[4];
+ if ((rlen = len)> (IPMI_SYSINFO_SET0_SIZE-3)) {
+ /* First set has 11 bytes */
+ rlen = IPMI_SYSINFO_SET0_SIZE - 3;
+ }
+ memcpy(address, data+8, rlen);
+ for (set = 1; len> 11; set++) {
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, set, dest, 19, data);
+ if ((rlen = len-11)>= IPMI_SYSINFO_SETN_SIZE - 2) {
+ /* Remaining sets have 14 bytes */
+ rlen = IPMI_SYSINFO_SETN_SIZE - 2;
+ }
+ memcpy(address+set*11, data+3, rlen);
+ len -= rlen+3;
+ }
+ ipmi_pef_print_str("IPv6 Address", address);
+}
+
+static void
ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
{ /*
// print LAN alert destination info
@@ -284,6 +332,10 @@ ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
return;
}
tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK);
+ if (dest> tbl_size) {
+ ipmi_pef_print_oem_lan_dest(intf, ch, dest - tbl_size);
+ return;
+ }
//if (tbl_size == 0 || dest == 0) /* LAN alerting not supported */
// return;
@@ -579,7 +631,7 @@ ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * bu
static void
ipmi_pef_print_entry(struct ipmi_rs * rsp, uint8_t id,
- struct pef_cfgparm_filter_table_entry * pef)
+ struct pef_cfgparm_filter_table_entry * pef)
{ /*
// print a PEF table entry
*/
@@ -686,50 +738,49 @@ ipmi_pef_list_policies(struct ipmi_intf * intf)
req.msg.data = &ch;
req.msg.data_len = sizeof(ch);
for (ptmp=ptbl, i=1; i<=tbl_size; i++, ptmp++) {
- if ((ptmp->entry.policy & PEF_POLICY_ENABLED) == PEF_POLICY_ENABLED) {
- if (i> 1)
- printf("\n");
- first_field = 1;
- ipmi_pef_print_dec("Alert policy table entry",
- (ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
- ipmi_pef_print_dec("Policy set",
- (ptmp->entry.policy & PEF_POLICY_ID_MASK)>> PEF_POLICY_ID_SHIFT);
- ipmi_pef_print_str("Policy entry rule",
- ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
-
- if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
- ipmi_pef_print_str("Event-specific", "true");
-// continue;
- }
- wrk = ptmp->entry.chan_dest;
-
- /* channel/description */
- ch = (wrk & PEF_POLICY_CHANNEL_MASK)>> PEF_POLICY_CHANNEL_SHIFT;
- rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
- if (!rsp || rsp->data[0] != ch) {
- lprintf(LOG_ERR, " **Error retrieving %s",
- "Channel info");
- continue;
- }
- medium = rsp->data[1];
- ipmi_pef_print_dec("Channel number", ch);
- ipmi_pef_print_str("Channel medium",
- ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
-
- /* destination/description */
- wrk &= PEF_POLICY_DESTINATION_MASK;
- switch (medium) {
- case PEF_CH_MEDIUM_TYPE_LAN:
- ipmi_pef_print_lan_dest(intf, ch, wrk);
- break;
- case PEF_CH_MEDIUM_TYPE_SERIAL:
- ipmi_pef_print_serial_dest(intf, ch, wrk);
- break;
- default:
- ipmi_pef_print_dest(intf, ch, wrk);
- break;
- }
+ first_field = 1;
+ ipmi_pef_print_dec("Alert policy table entry",
+ (ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
+ ipmi_pef_print_dec("Policy set",
+ (ptmp->entry.policy & PEF_POLICY_ID_MASK)>> PEF_POLICY_ID_SHIFT);
+ ipmi_pef_print_str("State",
+ ptmp->entry.policy & PEF_POLICY_ENABLED ? "enabled" : "disabled");
+ ipmi_pef_print_str("Policy entry rule",
+ ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
+
+ if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
+ ipmi_pef_print_str("Event-specific", "true");
+ // continue;
+ }
+ wrk = ptmp->entry.chan_dest;
+
+ /* channel/description */
+ ch = (wrk & PEF_POLICY_CHANNEL_MASK)>> PEF_POLICY_CHANNEL_SHIFT;
+ rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
+ if (!rsp || rsp->data[0] != ch) {
+ lprintf(LOG_ERR, " **Error retrieving %s",
+ "Channel info");
+ continue;
+ }
+ medium = rsp->data[1];
+ ipmi_pef_print_dec("Channel number", ch);
+ ipmi_pef_print_str("Channel medium",
+ ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
+
+ /* destination/description */
+ wrk &= PEF_POLICY_DESTINATION_MASK;
+ switch (medium) {
+ case PEF_CH_MEDIUM_TYPE_LAN:
+ ipmi_pef_print_lan_dest(intf, ch, wrk);
+ break;
+ case PEF_CH_MEDIUM_TYPE_SERIAL:
+ ipmi_pef_print_serial_dest(intf, ch, wrk);
+ break;
+ default:
+ ipmi_pef_print_dest(intf, ch, wrk);
+ break;
}
+ printf("\n");
}
free(ptbl);
ptbl = NULL;
@@ -858,33 +909,258 @@ ipmi_pef_get_info(struct ipmi_intf * intf)
ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, actions);
}
+int
+ipmi_pef_timer(struct ipmi_intf *intf, int argc, char **argv)
+{
+ lprintf(LOG_ERR, "Not implemented");
+ return (-1);
+}
+
+void
+ipmi_pef_policy_help(void)
+{
+ lprintf(LOG_NOTICE,
+ "usage: pef policy <command> [options");
+ lprintf(LOG_NOTICE,
+ " list List enabled PEF policies");
+}
+
+void
+ipmi_pef2_policy_help(void)
+{
+ lprintf(LOG_NOTICE, "usage: pef policy list");
+ lprintf(LOG_NOTICE, " pef policy enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef policy delete <id = 1..n>");
+}
+
+#define IPMI_CMD_SET_PEF_CONFIG_PARMS 0x12
+struct pef_cfgparm_set_policy_table_entry
+{
+ uint8_t id;
+ uint8_t sel;
+ struct pef_policy_entry entry;
+} ATTRIBUTE_PACKING;
+
+
+static int
+ipmi_pef_set_policy_table_entry(struct ipmi_intf * intf, int set, struct pef_cfgparm_policy_table_entry *entry)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct pef_cfgparm_set_policy_table_entry psel;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_SET_PEF_CONFIG_PARMS;
+ req.msg.data = &psel;
+ req.msg.data_len = sizeof(psel);
+
+ memset(&psel, 0, sizeof(psel));
+ psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
+ psel.sel = set & 0x3F;
+ memcpy(&psel.entry, &entry->entry, sizeof(entry->entry));
+
+ rsp = ipmi_pef_msg_exchange(intf, &req, "Set Alert policy table entry");
+ if (!rsp) {
+ lprintf(LOG_ERR, " **Error setting Alert policy table entry");
+ return -1;
+ }
+ return 0;
+}
+
+/* Enable/Disable specific PEF policy */
+static int
+ipmi_pef2_policy_enable(struct ipmi_intf *intf, int enable, int argc, char **argv)
+{
+ struct pef_cfgparm_policy_table_entry * ptbl = NULL;
+ int tbl_size, id;
+
+ if (argc < 1) {
+ ipmi_pef2_policy_help();
+ return (-1);
+ }
+ tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
+ if (!tbl_size) {
+ if (ptbl != NULL) {
+ free(ptbl);
+ }
+ return (-1);
+ }
+
+ /* Get policy ID number */
+ id = strtol(argv[0], NULL, 0);
+ if (id>= 1 && id <= tbl_size) {
+ /* Check if already enabled or disabled */
+ if ((enable && !(ptbl[id-1].entry.policy & PEF_POLICY_ENABLED)) ||
+ (!enable && (ptbl[id-1].entry.policy & PEF_POLICY_ENABLED))) {
+ ptbl[id-1].entry.policy ^= PEF_POLICY_ENABLED;
+ return ipmi_pef_set_policy_table_entry(intf, id, &ptbl[id-1]);
+ }
+ else {
+ lprintf(LOG_ERR, "Policy %d already %s", id, enable ? "enabled" : "disabled");
+ }
+ } else {
+ lprintf(LOG_ERR, "Invalid policy index, valid range = (1..%d)", tbl_size);
+ return (-1);
+ }
+ lprintf(LOG_INFO, "done\n");
+ return (0);
+}
+
+int
+ipmi_pef2_policy(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_policy_help();
+ rc = (-1);
+ } else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_policy_help();
+ }
+ else if (!strncmp(argv[0], "list\0", 5)) {
+ ipmi_pef_list_policies(intf);
+ }
+ else if (!strncmp(argv[0], "enable\0", 7)) {
+ rc = ipmi_pef2_policy_enable(intf, 1, --argc, ++argv);
+ }
+ else if (!strncmp(argv[0], "disable\0", 8)) {
+ rc = ipmi_pef2_policy_enable(intf, 0, --argc, ++argv);
+ }
+ else if (!strncmp(argv[0], "create\0", 7)) {
+ }
+ else if (!strncmp(argv[0], "delete\0", 7)) {
+ }
+ else {
+ ipmi_pef2_policy_help();
+ }
+ return rc;
+}
+
+/* Enable/Disable specific PEF filter */
+static int
+ipmi_pef2_filter_enable(struct ipmi_intf *intf, int enable, int argc, char **argv)
+{
+}
+
+void
+ipmi_pef2_filter_help(void)
+{
+ lprintf(LOG_NOTICE, "usage: pef filter list");
+ lprintf(LOG_NOTICE, " pef filter enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef filter delete <id = 1..n>");
+}
+
+int
+ipmi_pef2_filter(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_filter_help();
+ rc = (-1);
+ }
+ else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_filter_help();
+ }
+ else if (!strncmp(argv[0], "list\0", 5)) {
+ ipmi_pef_list_entries(intf);
+ }
+ else if (!strncmp(argv[0], "enable\0", 7)) {
+ }
+ else if (!strncmp(argv[0], "disable\0", 8)) {
+ }
+ else if (!strncmp(argv[0], "create\0", 7)) {
+ }
+ else if (!strncmp(argv[0], "delete\0", 7)) {
+ }
+ else {
+ //ipmi_pef2_filterhelp();
+ }
+ return rc;
+}
+
+void
+ipmi_pef2_help(void)
+{
+ lprintf(LOG_NOTICE, "usage: pef help");
+ lprintf(LOG_NOTICE, " pef timer get");
+ lprintf(LOG_NOTICE, " pef timer set");
+ lprintf(LOG_NOTICE, " pef policy list");
+ lprintf(LOG_NOTICE, " pef policy enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef policy delete <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter list");
+ lprintf(LOG_NOTICE, " pef filter enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef filter delete <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef pet ack <params>");
+}
+
+/*
+ pef help
+ pef timer get
+ pef timer set <xxx>
+ pef policy list
+ pef policy enable <id>
+ pef policy disable <id>
+ pef policy create <id> <params>
+ pef policy delete <id>
+ pef filter list
+ pef filter enable <id>
+ pef filter disable <id>
+ pef filter create <id> <params>
+ pef filter delete <id>
+ pef pet ack <params>
+*/
int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
{ /*
// PEF subcommand handling
*/
- int help = 0;
- int rc = 0;
-
- if (!argc || !strncmp(argv[0], "info", 4))
- ipmi_pef_get_info(intf);
- else if (!strncmp(argv[0], "help", 4))
- help = 1;
- else if (!strncmp(argv[0], "status", 6))
- ipmi_pef_get_status(intf);
- else if (!strncmp(argv[0], "policy", 6))
- ipmi_pef_list_policies(intf);
- else if (!strncmp(argv[0], "list", 4))
- ipmi_pef_list_entries(intf);
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_help();
+ rc = (-1);
+ }
+ else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_help();
+ rc = 0;
+ }
+ else if (!strncmp(argv[0], "info\0", 5)
+ || !strncmp(argv[0], "capabilities\0", 13)) {
+ //rc = ipmi_pef2_get_capabilities(intf);
+ }
+ else if (!strncmp(argv[0], "event\0", 6)) {
+ //rc = ipmi_pef2_event(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "filter\0", 7)) {
+ rc = ipmi_pef2_filter(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "policy\0", 7)) {
+ rc = ipmi_pef2_policy(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "pet\0", 4)) {
+ //rc = ipmi_pef2_pet(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "status\0", 7)) {
+ //rc = ipmi_pef2_get_status(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "timer\0", 6)) {
+ //rc = ipmi_pef2_timer(intf, (argc - 1), ++argv);
+ }
else {
- help = 1;
- rc = -1;
lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
+ rc = (-1);
}
-
- if (help)
- lprintf(LOG_NOTICE, "PEF commands: info status policy list");
- else if (!verbose)
- printf("\n");
-
return rc;
}
------------------------------------------------------------------------------
Support for this is needed for one of our utilities. A new rework of the whole PEF framework was
requested. I'm attaching a patch that (partially) implements this new scheme, please review.
http://sourceforge.net/p/ipmitool/bugs/312/
diff --git a/include/ipmitool/ipmi_mc.h b/include/ipmitool/ipmi_mc.h
index a840f78..fbd2c97 100644
--- a/include/ipmitool/ipmi_mc.h
+++ b/include/ipmitool/ipmi_mc.h
@@ -165,6 +165,8 @@ struct ipm_get_watchdog_rsp {
#define IPMI_SYSINFO_OS_NAME 0x04
#define IPMI_SYSINFO_DELL_OS_VERSION 0xe4
#define IPMI_SYSINFO_DELL_URL 0xde
+#define IPMI_SYSINFO_DELL_IPV6_COUNT 0xe6
+#define IPMI_SYSINFO_DELL_IPV6_DESTADDR 0xf0
int ipmi_mc_getsysinfo(struct ipmi_intf * intf, int param, int block, int set,
int len, void *buffer);
diff --git a/lib/ipmi_pef.c b/lib/ipmi_pef.c
index 1beebf0..fd52663 100644
--- a/lib/ipmi_pef.c
+++ b/lib/ipmi_pef.c
@@ -38,6 +38,7 @@
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_pef.h>
@@ -206,7 +207,7 @@ ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt)
static uint8_t
ipmi_pef_get_policy_table(struct ipmi_intf * intf,
- struct pef_cfgparm_policy_table_entry ** table)
+ struct pef_cfgparm_policy_table_entry ** table)
{ /*
// get the PEF policy table: allocate space, fillin, and return its size
// NB: the caller must free the returned area (when returned size> 0)
@@ -257,6 +258,53 @@ ipmi_pef_get_policy_table(struct ipmi_intf * intf,
}
static void
+ipmi_pef_print_oem_lan_dest(struct ipmi_intf *intf, uint8_t ch, uint8_t dest)
+{
+ int rc, i;
+ uint8_t data[32];
+ char address[128];
+ int len, set, rlen;
+
+ if (ipmi_get_oem(intf) != IPMI_OEM_DELL) {
+ return;
+ }
+ /* Get # of IPV6 trap destinations */
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_COUNT, 0x00, 0x00, 4, data);
+ if (rc != 0 || dest> data[0]) {
+ return;
+ }
+ ipmi_pef_print_str("Alert destination type", "xxx");
+ ipmi_pef_print_str("PET Community", "xxx");
+ ipmi_pef_print_dec("ACK timeout/retry (secs)", 0);
+ ipmi_pef_print_dec("Retries", 0);
+
+ /* Get IPv6 destination string (may be in multiple sets) */
+ memset(address, 0, sizeof(address));
+ memset(data, 0, sizeof(data));
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, 0x00, dest, 19, data);
+ if (rc != 0) {
+ return;
+ }
+ /* Total length of IPv6 string */
+ len = data[4];
+ if ((rlen = len)> (IPMI_SYSINFO_SET0_SIZE-3)) {
+ /* First set has 11 bytes */
+ rlen = IPMI_SYSINFO_SET0_SIZE - 3;
+ }
+ memcpy(address, data+8, rlen);
+ for (set = 1; len> 11; set++) {
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, set, dest, 19, data);
+ if ((rlen = len-11)>= IPMI_SYSINFO_SETN_SIZE - 2) {
+ /* Remaining sets have 14 bytes */
+ rlen = IPMI_SYSINFO_SETN_SIZE - 2;
+ }
+ memcpy(address+set*11, data+3, rlen);
+ len -= rlen+3;
+ }
+ ipmi_pef_print_str("IPv6 Address", address);
+}
+
+static void
ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
{ /*
// print LAN alert destination info
@@ -284,6 +332,10 @@ ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
return;
}
tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK);
+ if (dest> tbl_size) {
+ ipmi_pef_print_oem_lan_dest(intf, ch, dest - tbl_size);
+ return;
+ }
//if (tbl_size == 0 || dest == 0) /* LAN alerting not supported */
// return;
@@ -579,7 +631,7 @@ ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * bu
static void
ipmi_pef_print_entry(struct ipmi_rs * rsp, uint8_t id,
- struct pef_cfgparm_filter_table_entry * pef)
+ struct pef_cfgparm_filter_table_entry * pef)
{ /*
// print a PEF table entry
*/
@@ -686,50 +738,49 @@ ipmi_pef_list_policies(struct ipmi_intf * intf)
req.msg.data = &ch;
req.msg.data_len = sizeof(ch);
for (ptmp=ptbl, i=1; i<=tbl_size; i++, ptmp++) {
- if ((ptmp->entry.policy & PEF_POLICY_ENABLED) == PEF_POLICY_ENABLED) {
- if (i> 1)
- printf("\n");
- first_field = 1;
- ipmi_pef_print_dec("Alert policy table entry",
- (ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
- ipmi_pef_print_dec("Policy set",
- (ptmp->entry.policy & PEF_POLICY_ID_MASK)>> PEF_POLICY_ID_SHIFT);
- ipmi_pef_print_str("Policy entry rule",
- ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
-
- if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
- ipmi_pef_print_str("Event-specific", "true");
-// continue;
- }
- wrk = ptmp->entry.chan_dest;
-
- /* channel/description */
- ch = (wrk & PEF_POLICY_CHANNEL_MASK)>> PEF_POLICY_CHANNEL_SHIFT;
- rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
- if (!rsp || rsp->data[0] != ch) {
- lprintf(LOG_ERR, " **Error retrieving %s",
- "Channel info");
- continue;
- }
- medium = rsp->data[1];
- ipmi_pef_print_dec("Channel number", ch);
- ipmi_pef_print_str("Channel medium",
- ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
-
- /* destination/description */
- wrk &= PEF_POLICY_DESTINATION_MASK;
- switch (medium) {
- case PEF_CH_MEDIUM_TYPE_LAN:
- ipmi_pef_print_lan_dest(intf, ch, wrk);
- break;
- case PEF_CH_MEDIUM_TYPE_SERIAL:
- ipmi_pef_print_serial_dest(intf, ch, wrk);
- break;
- default:
- ipmi_pef_print_dest(intf, ch, wrk);
- break;
- }
+ first_field = 1;
+ ipmi_pef_print_dec("Alert policy table entry",
+ (ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
+ ipmi_pef_print_dec("Policy set",
+ (ptmp->entry.policy & PEF_POLICY_ID_MASK)>> PEF_POLICY_ID_SHIFT);
+ ipmi_pef_print_str("State",
+ ptmp->entry.policy & PEF_POLICY_ENABLED ? "enabled" : "disabled");
+ ipmi_pef_print_str("Policy entry rule",
+ ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
+
+ if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
+ ipmi_pef_print_str("Event-specific", "true");
+ // continue;
+ }
+ wrk = ptmp->entry.chan_dest;
+
+ /* channel/description */
+ ch = (wrk & PEF_POLICY_CHANNEL_MASK)>> PEF_POLICY_CHANNEL_SHIFT;
+ rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
+ if (!rsp || rsp->data[0] != ch) {
+ lprintf(LOG_ERR, " **Error retrieving %s",
+ "Channel info");
+ continue;
+ }
+ medium = rsp->data[1];
+ ipmi_pef_print_dec("Channel number", ch);
+ ipmi_pef_print_str("Channel medium",
+ ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
+
+ /* destination/description */
+ wrk &= PEF_POLICY_DESTINATION_MASK;
+ switch (medium) {
+ case PEF_CH_MEDIUM_TYPE_LAN:
+ ipmi_pef_print_lan_dest(intf, ch, wrk);
+ break;
+ case PEF_CH_MEDIUM_TYPE_SERIAL:
+ ipmi_pef_print_serial_dest(intf, ch, wrk);
+ break;
+ default:
+ ipmi_pef_print_dest(intf, ch, wrk);
+ break;
}
+ printf("\n");
}
free(ptbl);
ptbl = NULL;
@@ -858,33 +909,258 @@ ipmi_pef_get_info(struct ipmi_intf * intf)
ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, actions);
}
+int
+ipmi_pef_timer(struct ipmi_intf *intf, int argc, char **argv)
+{
+ lprintf(LOG_ERR, "Not implemented");
+ return (-1);
+}
+
+void
+ipmi_pef_policy_help(void)
+{
+ lprintf(LOG_NOTICE,
+ "usage: pef policy <command> [options");
+ lprintf(LOG_NOTICE,
+ " list List enabled PEF policies");
+}
+
+void
+ipmi_pef2_policy_help(void)
+{
+ lprintf(LOG_NOTICE, "usage: pef policy list");
+ lprintf(LOG_NOTICE, " pef policy enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef policy delete <id = 1..n>");
+}
+
+#define IPMI_CMD_SET_PEF_CONFIG_PARMS 0x12
+struct pef_cfgparm_set_policy_table_entry
+{
+ uint8_t id;
+ uint8_t sel;
+ struct pef_policy_entry entry;
+} ATTRIBUTE_PACKING;
+
+
+static int
+ipmi_pef_set_policy_table_entry(struct ipmi_intf * intf, int set, struct pef_cfgparm_policy_table_entry *entry)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct pef_cfgparm_set_policy_table_entry psel;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_SET_PEF_CONFIG_PARMS;
+ req.msg.data = &psel;
+ req.msg.data_len = sizeof(psel);
+
+ memset(&psel, 0, sizeof(psel));
+ psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
+ psel.sel = set & 0x3F;
+ memcpy(&psel.entry, &entry->entry, sizeof(entry->entry));
+
+ rsp = ipmi_pef_msg_exchange(intf, &req, "Set Alert policy table entry");
+ if (!rsp) {
+ lprintf(LOG_ERR, " **Error setting Alert policy table entry");
+ return -1;
+ }
+ return 0;
+}
+
+/* Enable/Disable specific PEF policy */
+static int
+ipmi_pef2_policy_enable(struct ipmi_intf *intf, int enable, int argc, char **argv)
+{
+ struct pef_cfgparm_policy_table_entry * ptbl = NULL;
+ int tbl_size, id;
+
+ if (argc < 1) {
+ ipmi_pef2_policy_help();
+ return (-1);
+ }
+ tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
+ if (!tbl_size) {
+ if (ptbl != NULL) {
+ free(ptbl);
+ }
+ return (-1);
+ }
+
+ /* Get policy ID number */
+ id = strtol(argv[0], NULL, 0);
+ if (id>= 1 && id <= tbl_size) {
+ /* Check if already enabled or disabled */
+ if ((enable && !(ptbl[id-1].entry.policy & PEF_POLICY_ENABLED)) ||
+ (!enable && (ptbl[id-1].entry.policy & PEF_POLICY_ENABLED))) {
+ ptbl[id-1].entry.policy ^= PEF_POLICY_ENABLED;
+ return ipmi_pef_set_policy_table_entry(intf, id, &ptbl[id-1]);
+ }
+ else {
+ lprintf(LOG_ERR, "Policy %d already %s", id, enable ? "enabled" : "disabled");
+ }
+ } else {
+ lprintf(LOG_ERR, "Invalid policy index, valid range = (1..%d)", tbl_size);
+ return (-1);
+ }
+ lprintf(LOG_INFO, "done\n");
+ return (0);
+}
+
+int
+ipmi_pef2_policy(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_policy_help();
+ rc = (-1);
+ } else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_policy_help();
+ }
+ else if (!strncmp(argv[0], "list\0", 5)) {
+ ipmi_pef_list_policies(intf);
+ }
+ else if (!strncmp(argv[0], "enable\0", 7)) {
+ rc = ipmi_pef2_policy_enable(intf, 1, --argc, ++argv);
+ }
+ else if (!strncmp(argv[0], "disable\0", 8)) {
+ rc = ipmi_pef2_policy_enable(intf, 0, --argc, ++argv);
+ }
+ else if (!strncmp(argv[0], "create\0", 7)) {
+ }
+ else if (!strncmp(argv[0], "delete\0", 7)) {
+ }
+ else {
+ ipmi_pef2_policy_help();
+ }
+ return rc;
+}
+
+/* Enable/Disable specific PEF filter */
+static int
+ipmi_pef2_filter_enable(struct ipmi_intf *intf, int enable, int argc, char **argv)
+{
+}
+
+void
+ipmi_pef2_filter_help(void)
+{
+ lprintf(LOG_NOTICE, "usage: pef filter list");
+ lprintf(LOG_NOTICE, " pef filter enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef filter delete <id = 1..n>");
+}
+
+int
+ipmi_pef2_filter(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_filter_help();
+ rc = (-1);
+ }
+ else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_filter_help();
+ }
+ else if (!strncmp(argv[0], "list\0", 5)) {
+ ipmi_pef_list_entries(intf);
+ }
+ else if (!strncmp(argv[0], "enable\0", 7)) {
+ }
+ else if (!strncmp(argv[0], "disable\0", 8)) {
+ }
+ else if (!strncmp(argv[0], "create\0", 7)) {
+ }
+ else if (!strncmp(argv[0], "delete\0", 7)) {
+ }
+ else {
+ //ipmi_pef2_filterhelp();
+ }
+ return rc;
+}
+
+void
+ipmi_pef2_help(void)
+{
+ lprintf(LOG_NOTICE, "usage: pef help");
+ lprintf(LOG_NOTICE, " pef timer get");
+ lprintf(LOG_NOTICE, " pef timer set");
+ lprintf(LOG_NOTICE, " pef policy list");
+ lprintf(LOG_NOTICE, " pef policy enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef policy create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef policy delete <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter list");
+ lprintf(LOG_NOTICE, " pef filter enable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter disable <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef filter create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE, " pef filter delete <id = 1..n>");
+ lprintf(LOG_NOTICE, " pef pet ack <params>");
+}
+
+/*
+ pef help
+ pef timer get
+ pef timer set <xxx>
+ pef policy list
+ pef policy enable <id>
+ pef policy disable <id>
+ pef policy create <id> <params>
+ pef policy delete <id>
+ pef filter list
+ pef filter enable <id>
+ pef filter disable <id>
+ pef filter create <id> <params>
+ pef filter delete <id>
+ pef pet ack <params>
+*/
int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
{ /*
// PEF subcommand handling
*/
- int help = 0;
- int rc = 0;
-
- if (!argc || !strncmp(argv[0], "info", 4))
- ipmi_pef_get_info(intf);
- else if (!strncmp(argv[0], "help", 4))
- help = 1;
- else if (!strncmp(argv[0], "status", 6))
- ipmi_pef_get_status(intf);
- else if (!strncmp(argv[0], "policy", 6))
- ipmi_pef_list_policies(intf);
- else if (!strncmp(argv[0], "list", 4))
- ipmi_pef_list_entries(intf);
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_help();
+ rc = (-1);
+ }
+ else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_help();
+ rc = 0;
+ }
+ else if (!strncmp(argv[0], "info\0", 5)
+ || !strncmp(argv[0], "capabilities\0", 13)) {
+ //rc = ipmi_pef2_get_capabilities(intf);
+ }
+ else if (!strncmp(argv[0], "event\0", 6)) {
+ //rc = ipmi_pef2_event(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "filter\0", 7)) {
+ rc = ipmi_pef2_filter(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "policy\0", 7)) {
+ rc = ipmi_pef2_policy(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "pet\0", 4)) {
+ //rc = ipmi_pef2_pet(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "status\0", 7)) {
+ //rc = ipmi_pef2_get_status(intf, (argc - 1), ++argv);
+ }
+ else if (!strncmp(argv[0], "timer\0", 6)) {
+ //rc = ipmi_pef2_timer(intf, (argc - 1), ++argv);
+ }
else {
- help = 1;
- rc = -1;
lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
+ rc = (-1);
}
-
- if (help)
- lprintf(LOG_NOTICE, "PEF commands: info status policy list");
- else if (!verbose)
- printf("\n");
-
return rc;
}
------------------------------------------------------------------------------