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;
 }
                                          
------------------------------------------------------------------------------
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

Reply via email to