History

iscsi_ibft: filter null v4-mapped v6 addresses

I've had reports of UEFI platforms failing iSCSI boot in various configurations, that ended up being caused by network initialization scripts getting tripped up by unexpected null addresses (0.0.0.0) being reported for gateways, dhcp servers, and dns servers. The tianocore EDK2 iSCSI driver generates an iBFT table that always uses IPv4-mapped IPv6 addresses for the NIC structure fields. This results in values that are "not present or not specified" being reported as ::ffff:0.0.0.0 rather than all zeros as specified. The iscsi_ibft module filters unspecified fields from the iBFT from sysfs, preventing userspace from using invalid values and making it easy to check for the presence of a value. This currently fails in regard to these mapped null addresses. In order to remain consistent with how the iBFT information is exposed, we should accommodate the behavior of the tianocore iSCSI driver as it's already in the wild in a large number of servers. Tested under qemu using an OVMF build of tianocore EDK2.

Chris Leech committed 11 years ago

Commit e6050b61 parent 39a88041 file · +21 −15Browse files

Unified · Split

drivers/firmware/iscsi_ibft.c+21−15
@@ -186,8 +186,20 @@ struct ibft_kobject { · 185 unmodified lines
186186
187187 static struct iscsi_boot_kset *boot_kset;
188188
189+/* fully null address */
189190 static const char nulls[16];
190191
192+/* IPv4-mapped IPv6 ::ffff:0.0.0.0 */
193+static const char mapped_nulls[16] = { 0x00, 0x00, 0x00, 0x00,
194+ 0x00, 0x00, 0x00, 0x00,
195+ 0x00, 0x00, 0xff, 0xff,
196+ 0x00, 0x00, 0x00, 0x00 };
197+
198+static int address_not_null(u8 *ip)
199+{
200+ return (memcmp(ip, nulls, 16) && memcmp(ip, mapped_nulls, 16));
201+}
202+
191203 /*
192204 * Helper functions to parse data properly.
193205 */
@@ -445,7 +457,7 @@ static umode_t ibft_check_nic_for(void *data, int type) · 251 unmodified lines
445457 rc = S_IRUGO;
446458 break;
447459 case ISCSI_BOOT_ETH_IP_ADDR:
448− if (memcmp(nic->ip_addr, nulls, sizeof(nic->ip_addr)))
460+ if (address_not_null(nic->ip_addr))
449461 rc = S_IRUGO;
450462 break;
451463 case ISCSI_BOOT_ETH_SUBNET_MASK:
@@ -456,21 +468,19 @@ static umode_t ibft_check_nic_for(void *data, int type) · 4 unmodified lines
456468 rc = S_IRUGO;
457469 break;
458470 case ISCSI_BOOT_ETH_GATEWAY:
459− if (memcmp(nic->gateway, nulls, sizeof(nic->gateway)))
471+ if (address_not_null(nic->gateway))
460472 rc = S_IRUGO;
461473 break;
462474 case ISCSI_BOOT_ETH_PRIMARY_DNS:
463− if (memcmp(nic->primary_dns, nulls,
464− sizeof(nic->primary_dns)))
475+ if (address_not_null(nic->primary_dns))
465476 rc = S_IRUGO;
466477 break;
467478 case ISCSI_BOOT_ETH_SECONDARY_DNS:
468− if (memcmp(nic->secondary_dns, nulls,
469− sizeof(nic->secondary_dns)))
479+ if (address_not_null(nic->secondary_dns))
470480 rc = S_IRUGO;
471481 break;
472482 case ISCSI_BOOT_ETH_DHCP:
473− if (memcmp(nic->dhcp, nulls, sizeof(nic->dhcp)))
483+ if (address_not_null(nic->dhcp))
474484 rc = S_IRUGO;
475485 break;
476486 case ISCSI_BOOT_ETH_VLAN:
@@ -536,23 +546,19 @@ static umode_t __init ibft_check_initiator_for(void *data, int type) · 59 unmodified lines
536546 rc = S_IRUGO;
537547 break;
538548 case ISCSI_BOOT_INI_ISNS_SERVER:
539− if (memcmp(init->isns_server, nulls,
540− sizeof(init->isns_server)))
549+ if (address_not_null(init->isns_server))
541550 rc = S_IRUGO;
542551 break;
543552 case ISCSI_BOOT_INI_SLP_SERVER:
544− if (memcmp(init->slp_server, nulls,
545− sizeof(init->slp_server)))
553+ if (address_not_null(init->slp_server))
546554 rc = S_IRUGO;
547555 break;
548556 case ISCSI_BOOT_INI_PRI_RADIUS_SERVER:
549− if (memcmp(init->pri_radius_server, nulls,
550− sizeof(init->pri_radius_server)))
557+ if (address_not_null(init->pri_radius_server))
551558 rc = S_IRUGO;
552559 break;
553560 case ISCSI_BOOT_INI_SEC_RADIUS_SERVER:
554− if (memcmp(init->sec_radius_server, nulls,
555− sizeof(init->sec_radius_server)))
561+ if (address_not_null(init->sec_radius_server))
556562 rc = S_IRUGO;
557563 break;
558564 case ISCSI_BOOT_INI_INITIATOR_NAME: