[PATCH phosphor-host-ipmid] Implement Network Override

OpenBMC Patches openbmc-patches at stwcx.xyz
Tue Jun 7 04:00:44 AEST 2016


From: ratagupt <ratagupt at in.ibm.com>

---
 chassishandler.C | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 220 insertions(+), 8 deletions(-)

diff --git a/chassishandler.C b/chassishandler.C
index d5b3404..e21d6da 100644
--- a/chassishandler.C
+++ b/chassishandler.C
@@ -3,15 +3,19 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
-
-
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <string>
+using namespace std;
 //Defines
 #define SET_PARM_VERSION 1
 #define SET_PARM_BOOT_FLAGS_PERMANENT 0x40 //boot flags data1 7th bit on
 #define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME   0x80 //boot flags data1 8th bit on
 #define SET_PARM_BOOT_FLAGS_VALID_PERMANENT  0xC0 //boot flags data1 7 & 8 bit on 
-
-
+#define SIZE_MAC 18
+#define SIZE_HOST_NETWORK_DATA 26
+#define SIZE_BOOT_OPTION SIZE_HOST_NETWORK_DATA
+//#define INET_ADDRSTRLEN 15
 
 // OpenBMC Chassis Manager dbus framework
 const char  *chassis_bus_name      =  "org.openbmc.control.Chassis";
@@ -233,14 +237,197 @@ struct get_sys_boot_options_t {
 struct get_sys_boot_options_response_t {
     uint8_t version;
     uint8_t parm;
-    uint8_t data[5];
+    uint8_t data[SIZE_BOOT_OPTION];
 }  __attribute__ ((packed));
 
 struct set_sys_boot_options_t {
     uint8_t parameter;
-    uint8_t data[8];
+    uint8_t data[SIZE_BOOT_OPTION];
 }  __attribute__ ((packed));
 
+struct host_network_config_t {
+     string ipaddress;
+     string prefix;
+     string gateway;
+     string macaddress;
+     string isDHCP;
+
+     host_network_config_t()
+     {
+         ipaddress = "";
+         prefix = "";
+         gateway = "";
+         macaddress = "";
+         isDHCP = "";
+     }
+};
+
+uint8_t getHostNetworkData(get_sys_boot_options_response_t* respptr)
+{
+
+
+    printf ("Inside getHostNetworkData");
+    char * prop = NULL;
+
+    uint8_t data[SIZE_BOOT_OPTION]={0x80,0x21, 0x70 ,0x62 ,0x21,0x00 ,0x01 ,0x06 ,0x04};
+
+    //As first 9 bytes are prefilled so in rest of the bytes we are assigning 0
+
+    memset( data+9 ,0,(SIZE_BOOT_OPTION-9) );
+
+    int rc = dbus_get_property("network_config",&prop);
+
+    if (rc < 0) {
+        fprintf(stderr, "Dbus get property(boot_flags) failed for get_sys_boot_options.\n");
+        return rc;
+    }
+
+    /* network_config property Value would be in the form of 
+     * ipaddress=1.1.1.1,prefix=16,gateway=2.2.2.2,mac=11:22:33:44:55:66,dhcp=0
+     */
+
+    /* Parsing the string and fill the hostconfig structure with the 
+     * values */
+
+    host_network_config_t host_config;
+    string delimiter = ",";
+
+    int pos = 0;
+    string token,name,value;
+    string conf_str(prop);
+    
+    printf ("Configuration String[%s]\n ",conf_str.c_str());
+
+    while ((pos = conf_str.find(delimiter)) != std::string::npos) {
+
+        token = conf_str.substr(0, pos);
+        int pos1 = token.find("=");
+
+        name = token.substr(0,pos1);
+        value = token.substr(pos1+1,pos);
+
+        if ( name == "ipaddress" )
+            host_config.ipaddress = value;
+        else if ( name == "prefix")
+            host_config.prefix = value; 
+        else if ( name == "gateway" )
+            host_config.gateway = value;
+        else if ( name == "mac" )
+            host_config.macaddress = value;
+        else if ( name == "dhcp" )
+            host_config.isDHCP = value;
+
+        conf_str.erase(0, pos + delimiter.length());
+        printf ("Name=[%s],Value=[%s],position=[%d]\n",name.c_str(),value.c_str(),pos);
+    }
+
+    //Converting the mac address as number//
+    //If there as an error in converting the mac as number we are not throwing 
+    //error we would be sending 0's for the mac.
+    
+    char *tokptr = NULL;
+    char* digit = strtok_r((char *)host_config.macaddress.c_str(), ":", &tokptr);
+    if (digit == NULL)
+    {
+        fprintf(stderr, "Unexpected MAC format: %s", host_config.macaddress.c_str());
+    }
+    
+    //As 9 bytes are pre filled so staring from index 9.If there is a failure 
+    //in the strtok_r then digit will be null then we don't need to do 
+    //anything as data is prefilled with 0
+    
+    uint8_t index=9;
+
+    while (digit != NULL)
+    {
+        int resp_byte = strtoul(digit, NULL, 16);
+        memcpy((void*)&data[index], &resp_byte, 1);
+        index++;
+        digit = strtok_r(NULL, ":", &tokptr);
+    }
+
+    //Conevrt the dhcp,ipaddress,mask and gateway as hex number
+    data[index++]=0x00;
+    sscanf(host_config.isDHCP.c_str(),"%02X",&data[index++]);
+
+    inet_pton(AF_INET,host_config.ipaddress.c_str(),(void *)&data[index]);
+    index+=4;
+    sscanf(host_config.prefix.c_str(),"%02X",&data[index++]);
+    inet_pton(AF_INET,host_config.gateway.c_str(),(void *)&data[index]);
+    index+=4; 
+
+    printf ("\n===========Printing the Network Conf=====================\n");
+
+    for (int j = 0;j<index;j++)
+        printf("%02x ", data[j]);
+
+    memcpy(respptr->data,data,SIZE_BOOT_OPTION);
+    return 0;
+
+}
+
+uint8_t setHostNetworkData(set_sys_boot_options_t * reqptr)
+{
+    printf ("\n Inside setHostNetworkData***********");
+    string host_network_config;
+    char mac[SIZE_MAC];
+    char ipAddress[INET_ADDRSTRLEN];
+    char gateway[INET_ADDRSTRLEN];
+    char prefix[1];
+    char dhcp[2];
+    uint32_t cookie = 0;
+
+
+    memset( mac ,0,SIZE_MAC );
+    memset(ipAddress,0,INET_ADDRSTRLEN);
+    memset(gateway,0,INET_ADDRSTRLEN);
+    memset(prefix,0,1);
+    memset(dhcp,0,2);
+
+    uint8_t index = 9;  
+    sscanf((char *)&(reqptr->data[1]),"%02X",&cookie);
+
+    if ( !cookie) {
+     
+         snprintf(mac, SIZE_MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
+            reqptr->data[index],
+            reqptr->data[index+1],
+            reqptr->data[index+2],
+            reqptr->data[index+3],
+            reqptr->data[index+4],
+            reqptr->data[index+5]);
+
+
+        snprintf(dhcp,2, "%d", reqptr->data[index+6]);
+
+        snprintf(ipAddress, INET_ADDRSTRLEN, "%d.%d.%d.%d",
+            reqptr->data[index+8], reqptr->data[index+9], reqptr->data[index+10], reqptr->data[index+11]);
+
+        snprintf(prefix, INET_ADDRSTRLEN, "%d", reqptr->data[index+12]);
+
+
+        snprintf(gateway, INET_ADDRSTRLEN, "%d.%d.%d.%d",
+            reqptr->data[index+13], reqptr->data[index+14], reqptr->data[index+15], reqptr->data[index+16]);
+    }
+
+    host_network_config += "ipaddress="+string(ipAddress)+",prefix="+ \
+                       string(prefix)+",gateway="+string(gateway)+\
+                       ",mac="+string(mac)+",dhcp="+string(dhcp);
+
+
+    printf ("Host Config Str= %s\n",host_network_config.c_str());
+
+    int r = dbus_set_property("network_config",host_network_config.c_str());
+
+    if (r < 0) {
+        fprintf(stderr, "Dbus set property(network_config) failed for set_sys_boot_options.\n");
+        r = IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    return r;
+
+}
+
 ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
                               ipmi_request_t request, ipmi_response_t response, 
                               ipmi_data_len_t data_len, ipmi_context_t context)
@@ -446,7 +633,18 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
         }
 
 
-    } else {
+    } else if ( reqptr->parameter == 0x61 ) {
+       resp->parm      = 0x61;
+       int ret = getHostNetworkData(resp);
+       if (ret < 0) {
+           fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
+           rc = IPMI_CC_UNSPECIFIED_ERROR;
+
+       }else
+          rc = IPMI_CC_OK;
+    }
+
+    else {
         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
     }
 
@@ -476,6 +674,9 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
      * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
      * This is the only parameter used by petitboot.
      */
+
+
+    printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
     if (reqptr->parameter == 5) {
 
         s = get_boot_option_by_ipmi(((reqptr->data[1] & 0x3C) >> 2));
@@ -507,7 +708,18 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
             rc = IPMI_CC_UNSPECIFIED_ERROR;
         }
 
-    } else {
+    }
+    else if ( reqptr->parameter == 0x61 ) {
+       printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
+       int ret = setHostNetworkData(reqptr);
+       if (ret < 0) {
+           fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
+           rc = IPMI_CC_UNSPECIFIED_ERROR;
+
+       }
+    }      
+    
+    else {
         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
         rc = IPMI_CC_PARM_NOT_SUPPORTED;
     }
-- 
2.8.3




More information about the openbmc mailing list