From 79f738d13fa491abac82c77ac42f59aef4217b1d Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Mon, 21 Mar 2016 16:35:05 +1100 Subject: discover: Respect persistent flag for network overrides If the persistent bit is set in a IPMI network override, overwrite any existing interface config in NVRAM with the new network override. Signed-off-by: Samuel Mendoza-Jonas --- discover/ipmi.c | 20 +++++++++++--------- discover/ipmi.h | 2 +- discover/platform-powerpc.c | 20 ++++++++++++++++---- 3 files changed, 28 insertions(+), 14 deletions(-) (limited to 'discover') diff --git a/discover/ipmi.c b/discover/ipmi.c index e52070f..38423b2 100644 --- a/discover/ipmi.c +++ b/discover/ipmi.c @@ -223,7 +223,7 @@ bool ipmi_present(void) /* Reads and applies an IPMI interface config override, which closely follows * the format of an interface config struct as described in lib/types */ -void parse_ipmi_interface_override(struct config *config, uint8_t *buf, +int parse_ipmi_interface_override(struct config *config, uint8_t *buf, uint16_t len) { struct interface_config *ifconf; @@ -240,14 +240,14 @@ void parse_ipmi_interface_override(struct config *config, uint8_t *buf, if (!hwsize || !ipsize) { pb_log("%s: Empty response\n", __func__); - return; + return -1; } /* At the moment only support 6-byte MAC addresses */ if (hwsize != sizeof(ifconf->hwaddr)) { pb_log("Unsupported HW address size in network override: %u\n", hwsize); - return; + return -1; } /* Sanity check the IP address size */ @@ -259,14 +259,14 @@ void parse_ipmi_interface_override(struct config *config, uint8_t *buf, addr_len = INET6_ADDRSTRLEN; } else { pb_log("Unsupported IP address size: %u\n", ipsize); - return; + return -1; } /* Everything past here is the interface config */ ifconf = talloc_zero(config, struct interface_config); if (!ifconf) { pb_log("Failed to allocate network override\n"); - return; + return -1; } /* Hardware Address */ @@ -281,7 +281,7 @@ void parse_ipmi_interface_override(struct config *config, uint8_t *buf, if (ipsize + ipsize + 1 > len - i) { pb_log("Expected data greater than buffer size\n"); talloc_free(ifconf); - return; + return -1; } /* IP address */ @@ -289,7 +289,7 @@ void parse_ipmi_interface_override(struct config *config, uint8_t *buf, if (!inet_ntop(addr_type, &buf[i], ipstr, addr_len)) { pb_log("Failed to convert ipaddr: %m\n"); talloc_free(ifconf); - return; + return -1; } i += ipsize; @@ -303,17 +303,19 @@ void parse_ipmi_interface_override(struct config *config, uint8_t *buf, if (!inet_ntop(addr_type, &buf[i], gatewaystr, addr_len)) { pb_log("Failed to convert gateway: %m\n"); talloc_free(ifconf); - return; + return -1; } ifconf->static_config.gateway = gatewaystr; i += ipsize; } - pb_log("Applying IPMI network config\n"); + pb_log("Applying IPMI network interface override\n"); /* Replace any existing interface config */ talloc_free(config->network.interfaces); config->network.n_interfaces = 1; config->network.interfaces = talloc(config, struct interface_config *); config->network.interfaces[0] = ifconf; + + return 0; } diff --git a/discover/ipmi.h b/discover/ipmi.h index 85c91f4..af8df35 100644 --- a/discover/ipmi.h +++ b/discover/ipmi.h @@ -38,7 +38,7 @@ int ipmi_transaction(struct ipmi *ipmi, uint8_t netfn, uint8_t cmd, uint8_t *resp_buf, uint16_t *resp_len, int timeout_ms); -void parse_ipmi_interface_override(struct config *config, uint8_t *buf, +int parse_ipmi_interface_override(struct config *config, uint8_t *buf, uint16_t len); diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c index 0e3a10b..b426df6 100644 --- a/discover/platform-powerpc.c +++ b/discover/platform-powerpc.c @@ -1121,6 +1121,7 @@ static void get_ipmi_network_override(struct platform_powerpc *platform, const uint32_t magic_value = 0x21706221; uint8_t resp[resp_len]; uint32_t cookie; + bool persistent; int i, rc; uint8_t req[] = { 0x61, /* parameter selector: OEM section (network) */ @@ -1169,18 +1170,21 @@ static void get_ipmi_network_override(struct platform_powerpc *platform, return; } - /* Check for valid parameters. For now ignore the persistent flag */ + /* Check that the parameters are valid */ if (resp[2] & 0x80) { pb_debug("platform: network override is invalid/locked\n"); return; } - /* Check for valid parameters in the boot flags section, ignoring the - * persistent bit */ + /* Check for valid parameters in the boot flags section */ if (!(resp[3] & 0x80)) { pb_debug("platform: network override valid flag not set\n"); return; } + /* Read the persistent flag; if it is set we need to save this config */ + persistent = resp[3] & 0x40; + if (persistent) + pb_debug("platform: network override is persistent\n"); /* Check 4-byte cookie value */ i = 4; @@ -1202,7 +1206,15 @@ static void get_ipmi_network_override(struct platform_powerpc *platform, } /* Interpret the rest of the interface config */ - parse_ipmi_interface_override(config, &resp[i], resp_len - i); + rc = parse_ipmi_interface_override(config, &resp[i], resp_len - i); + + if (!rc && persistent) { + /* Write this new config to NVRAM */ + update_network_config(platform, config); + rc = write_nvram(platform); + if (rc) + pb_log("platform: Failed to save persistent interface override\n"); + } } static int load_config(struct platform *p, struct config *config) -- cgit v1.2.1