qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* Add support for retrieving fake LAN config from `ipmi-bmc-sim` device
@ 2025-06-27 17:13 Yunpeng Yang
  2025-08-03 11:15 ` Yunpeng Yang
  0 siblings, 1 reply; 7+ messages in thread
From: Yunpeng Yang @ 2025-06-27 17:13 UTC (permalink / raw)
  To: minyard@acm.org; +Cc: qemu-devel@nongnu.org, Mark Cave-Ayland, Jonathan Davies


[-- Attachment #1.1: Type: text/plain, Size: 1187 bytes --]

Hello Corey Minyard,

I hope this email finds you well.

I'm currently adding LAN-configs-retrieval support to the QEMU ipmi-bmc-sim device. And I hope to merge the modifications upstream after it's finished. Could you please check the attached patch file of the draft code and share your opinions and advice?

In my work, we need to run tools like "ipmitool lan print" on a VM for testing purposes. However, QEMU internal BMC simulator device (`ipmi-bmc-sim`) does not support retrieving LAN configs from it. I have to implement two IPMI commands so that the device can now work with ipmitool. The LAN config values are faked, but for testing purposes this is not a problem. I believe other people may also have the same need, so it's worth getting merged upstream.

The fake BMC LAN config values are currently hard coded into the code. My plan is to add a parameter to the device, which is a file containing user designated values. The device then reads the file and returns those values as LAN configs. This is similar to sdrfile for sensor data and frudatafile for FRU data.

Looking forward to hearing your thoughts.
Have a nice weekend.

Kind regards,
Yunpeng Yang

[-- Attachment #1.2: Type: text/html, Size: 4652 bytes --]

[-- Attachment #2: 0001-hw-ipmi-ipmi_bmc_sim.c-generating-fake-LAN-channel-i.patch --]
[-- Type: application/octet-stream, Size: 10007 bytes --]

From a8658d0c6028c9bd978d43e843fff4c8abd387a5 Mon Sep 17 00:00:00 2001
From: Yunpeng Yang <yunpeng.yang@nutanix.com>
Date: Wed, 11 Jun 2025 11:40:25 +0000
Subject: [PATCH] hw/ipmi/ipmi_bmc_sim.c: generating fake LAN channel info

Add partial support for two IPMI commands, "Get Channel Info Command"
and "Get LAN Configuration Parameters Command", to the qemu
`ipmi_bmc_sim` device. Fake BMC LAN channel info will be generated for
these two commands.

`ipmitool lan print` can now be run on a qemu VM to retrieve the fake
BMC LAN info if `ipmi_bmc_sim` is enabled.

IPMI2.0 interface specification:
https://www.intel.com/content/www/us/en/products/docs/servers/
ipmi/ipmi-second-gen-interface-spec-v2-rev1-1.html

Change-Id: Ia841c6f996d7a1d85ad35128b99790397bd40d7c
---
 hw/ipmi/ipmi_bmc_sim.c | 181 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 181 insertions(+)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 905e091094..dacebb9d78 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -70,6 +70,7 @@
 #define IPMI_CMD_GET_MSG                  0x33
 #define IPMI_CMD_SEND_MSG                 0x34
 #define IPMI_CMD_READ_EVT_MSG_BUF         0x35
+#define IPMI_CMD_GET_CHANNEL_INFO         0x42
 
 #define IPMI_NETFN_STORAGE            0x0a
 
@@ -100,6 +101,10 @@
 #define IPMI_CMD_GET_SEL_TIME             0x48
 #define IPMI_CMD_SET_SEL_TIME             0x49
 
+#define IPMI_NETFN_TRANSPORT          0x0c
+
+#define IPMI_CMD_GET_LAN_CONFIG           0x02
+
 
 /* Same as a timespec struct. */
 struct ipmi_time {
@@ -263,6 +268,28 @@ struct IPMIBmcSim {
 #define IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN      2
 #define IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE     3
 
+/*
+ * Refer to the IPMI2.0 interface specification:
+ * https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/
+ *     ipmi-second-gen-interface-spec-v2-rev1-1.pdf
+ */
+#define IPMI_BMC_LAN_CFG_PARAMETER_REVISION        0x11
+#define IPMI_BMC_LAN_CFG_CC_PARAM_NOT_SUPPORTED    0x80
+#define IPMI_BMC_LAN_CFG_PARAM_SET_IN_PROGRESS          0x00
+#define IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_SUPPORT        0x01
+#define IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_ENABLES        0x02
+#define IPMI_BMC_LAN_CFG_PARAM_IP_ADDR                  0x03
+#define IPMI_BMC_LAN_CFG_PARAM_IP_ADDR_SOURCE           0x04
+#define IPMI_BMC_LAN_CFG_PARAM_MAC_ADDR                 0x05
+#define IPMI_BMC_LAN_CFG_PARAM_SUBNET_MASK              0x06
+#define IPMI_BMC_LAN_CFG_PARAM_IPV4_HDR_PARAM           0x07
+#define IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_ADDR          0x0c
+#define IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_MAC_ADDR      0x0d
+#define IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_ADDR           0x0e
+#define IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_MAC_ADDR       0x0f
+#define IPMI_BMC_LAN_CFG_PARAM_COMMUNITY_STRING         0x10
+#define IPMI_BMC_LAN_CFG_PARAM_NUM_DESTINATIONS         0x11
+
 #define RSP_BUFFER_INITIALIZER { }
 
 static inline void rsp_buffer_pushmore(RspBuffer *rsp, uint8_t *bytes,
@@ -1219,6 +1246,37 @@ static void get_watchdog_timer(IPMIBmcSim *ibs,
     }
 }
 
+/*
+ * TODO: Add a `chnlfile=` parameter to the `ipmi_bmc_sim` device.
+ * Use that file to specify the channel info.
+ * If a channel is a LAN channel, include LAN parameters in that file.
+ */
+static void get_channel_info(IPMIBmcSim *ibs,
+                             uint8_t *cmd, unsigned int cmd_len,
+                             RspBuffer *rsp)
+{
+    uint8_t channel = cmd[2] & 0xf;
+    /* Refer to IPMI protocol for channel number assignments */
+    switch (channel) {
+    case 1:
+        rsp_buffer_push(rsp, 1); /* Actual channel number */
+        rsp_buffer_push(rsp, 0x4); /* Channel medium type: 802.3 LAN */
+        rsp_buffer_push(rsp, 0x0); /* Channel protocol: type n/a */
+        rsp_buffer_push(rsp, 0x0); /* Session support: session less */
+        /* 3-byte Vendor ID: IPMI Enterprise Number 7154 (LSB first) */
+        rsp_buffer_push(rsp, 0xf2);
+        rsp_buffer_push(rsp, 0x1b);
+        rsp_buffer_push(rsp, 0x00);
+        /* 2-byte Auxiliary Channel Info */
+        rsp_buffer_push(rsp, 0x0);
+        rsp_buffer_push(rsp, 0x0);
+        break;
+    default:
+        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
+        break;
+    }
+}
+
 static void get_sdr_rep_info(IPMIBmcSim *ibs,
                              uint8_t *cmd, unsigned int cmd_len,
                              RspBuffer *rsp)
@@ -1971,6 +2029,118 @@ static void set_sensor_reading(IPMIBmcSim *ibs,
     }
 }
 
+/*
+ * bytes   parameter
+ *    1    [7] revision only flag, [3:0] channel number
+ *    2    parameter selector
+ *    3    set selector
+ *    4    block selector
+ */
+static void get_lan_config(IPMIBmcSim *ibs,
+                            uint8_t *cmd, unsigned int cmd_len,
+                            RspBuffer *rsp)
+{
+    rsp_buffer_push(rsp, IPMI_BMC_LAN_CFG_PARAMETER_REVISION);
+    /* The requester only requests parameter revision, not the parameter */
+    if (cmd[2] & 0x80) {
+        return;
+    }
+
+    switch (cmd[3]) {
+    case IPMI_BMC_LAN_CFG_PARAM_SET_IN_PROGRESS:
+        rsp_buffer_push(rsp, 0x00); /* set complete */
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_SUPPORT:
+        rsp_buffer_push(rsp, 0x01); /* Authentication type "none" supported */
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_ENABLES:
+        /* Only authentication type "none" enabled */
+        rsp_buffer_push(rsp, 0x01); /* for privilege level "Callback" */
+        rsp_buffer_push(rsp, 0x01); /* for privilege level "User" */
+        rsp_buffer_push(rsp, 0x01); /* for privilege level "Operator" */
+        rsp_buffer_push(rsp, 0x01); /* for privilege level "Administrator" */
+        rsp_buffer_push(rsp, 0x01); /* for privilege level "OEM" */
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_IP_ADDR:
+        /* 192.0.2.1 */
+        rsp_buffer_push(rsp, 0xc0);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x02);
+        rsp_buffer_push(rsp, 0x01);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_IP_ADDR_SOURCE:
+        rsp_buffer_push(rsp, 0x00); /* unspecified address source */
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_MAC_ADDR:
+        /* 02:00:00:00:00:01 */
+        rsp_buffer_push(rsp, 0x02);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x01);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_SUBNET_MASK:
+        /* 255.255.255.0 */
+        rsp_buffer_push(rsp, 0xff);
+        rsp_buffer_push(rsp, 0xff);
+        rsp_buffer_push(rsp, 0xff);
+        rsp_buffer_push(rsp, 0x00);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_IPV4_HDR_PARAM:
+        rsp_buffer_push(rsp, 0x40);
+        rsp_buffer_push(rsp, 0x40);
+        rsp_buffer_push(rsp, 0x10);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_ADDR:
+        /* 192.0.2.1 */
+        rsp_buffer_push(rsp, 0xc0);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x02);
+        rsp_buffer_push(rsp, 0x01);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_MAC_ADDR:
+        /* 02:00:00:00:00:01 */
+        rsp_buffer_push(rsp, 0x02);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x01);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_ADDR:
+        /* 0.0.0.0 */
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_MAC_ADDR:
+        /* 00:00:00:00:00:00 */
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        rsp_buffer_push(rsp, 0x00);
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_COMMUNITY_STRING:
+        {
+            /* Better for `community_str` to be const,
+             * but `rsp_buffer_pushmore` requires non-const */
+            static uint8_t community_str[18] = "public";
+            rsp_buffer_pushmore(rsp, community_str, sizeof(community_str));
+        }
+        break;
+    case IPMI_BMC_LAN_CFG_PARAM_NUM_DESTINATIONS:
+        rsp_buffer_push(rsp, 0x00); /* LAN Alerting not supported */
+        break;
+    default :
+        rsp_buffer_set_error(rsp, IPMI_BMC_LAN_CFG_CC_PARAM_NOT_SUPPORTED);
+        return;
+    };
+}
+
 static const IPMICmdHandler chassis_cmds[] = {
     [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = { chassis_capabilities },
     [IPMI_CMD_GET_CHASSIS_STATUS] = { chassis_status },
@@ -2015,6 +2185,7 @@ static const IPMICmdHandler app_cmds[] = {
     [IPMI_CMD_RESET_WATCHDOG_TIMER] = { reset_watchdog_timer },
     [IPMI_CMD_SET_WATCHDOG_TIMER] = { set_watchdog_timer, 8 },
     [IPMI_CMD_GET_WATCHDOG_TIMER] = { get_watchdog_timer },
+    [IPMI_CMD_GET_CHANNEL_INFO] = { get_channel_info, 3 },
 };
 static const IPMINetfn app_netfn = {
     .cmd_nums = ARRAY_SIZE(app_cmds),
@@ -2044,12 +2215,22 @@ static const IPMINetfn storage_netfn = {
     .cmd_handlers = storage_cmds
 };
 
+static const IPMICmdHandler transport_cmds[] = {
+    [IPMI_CMD_GET_LAN_CONFIG] = { get_lan_config, 6 }
+};
+static const IPMINetfn transport_netfn = {
+    .cmd_nums = ARRAY_SIZE(transport_cmds),
+    .cmd_handlers = transport_cmds
+};
+
+
 static void register_cmds(IPMIBmcSim *s)
 {
     ipmi_sim_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
     ipmi_sim_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
     ipmi_sim_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
     ipmi_sim_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
+    ipmi_sim_register_netfn(s, IPMI_NETFN_TRANSPORT, &transport_netfn);
 }
 
 static uint8_t init_sdrs[] = {
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-10-20  8:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-27 17:13 Add support for retrieving fake LAN config from `ipmi-bmc-sim` device Yunpeng Yang
2025-08-03 11:15 ` Yunpeng Yang
2025-08-03 13:22   ` Corey Minyard
2025-08-04 12:08     ` Yunpeng Yang
2025-10-14 12:19     ` Yunpeng Yang
2025-10-14 23:17       ` Corey Minyard
2025-10-20  8:34         ` Yunpeng Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).