aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Leech <cleech@redhat.com>2015-05-28 15:51:51 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2015-06-05 21:07:02 -0400
commite6050b61df8a8765ce4e99da0b593d781c7fdfb1 (patch)
tree40efc1ec8f4b228fbc44b1bf47e4a29b622f2a7b
parent39a8804455fb23f09157341d3ba7db6d7ae6ee76 (diff)
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. Signed-off-by: Chris Leech <cleech@redhat.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--drivers/firmware/iscsi_ibft.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 071c2c969eec..72791232e46b 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -186,8 +186,20 @@ struct ibft_kobject {
186 186
187static struct iscsi_boot_kset *boot_kset; 187static struct iscsi_boot_kset *boot_kset;
188 188
189/* fully null address */
189static const char nulls[16]; 190static const char nulls[16];
190 191
192/* IPv4-mapped IPv6 ::ffff:0.0.0.0 */
193static 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
198static int address_not_null(u8 *ip)
199{
200 return (memcmp(ip, nulls, 16) && memcmp(ip, mapped_nulls, 16));
201}
202
191/* 203/*
192 * Helper functions to parse data properly. 204 * Helper functions to parse data properly.
193 */ 205 */
@@ -445,7 +457,7 @@ static umode_t ibft_check_nic_for(void *data, int type)
445 rc = S_IRUGO; 457 rc = S_IRUGO;
446 break; 458 break;
447 case ISCSI_BOOT_ETH_IP_ADDR: 459 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))
449 rc = S_IRUGO; 461 rc = S_IRUGO;
450 break; 462 break;
451 case ISCSI_BOOT_ETH_SUBNET_MASK: 463 case ISCSI_BOOT_ETH_SUBNET_MASK:
@@ -456,21 +468,19 @@ static umode_t ibft_check_nic_for(void *data, int type)
456 rc = S_IRUGO; 468 rc = S_IRUGO;
457 break; 469 break;
458 case ISCSI_BOOT_ETH_GATEWAY: 470 case ISCSI_BOOT_ETH_GATEWAY:
459 if (memcmp(nic->gateway, nulls, sizeof(nic->gateway))) 471 if (address_not_null(nic->gateway))
460 rc = S_IRUGO; 472 rc = S_IRUGO;
461 break; 473 break;
462 case ISCSI_BOOT_ETH_PRIMARY_DNS: 474 case ISCSI_BOOT_ETH_PRIMARY_DNS:
463 if (memcmp(nic->primary_dns, nulls, 475 if (address_not_null(nic->primary_dns))
464 sizeof(nic->primary_dns)))
465 rc = S_IRUGO; 476 rc = S_IRUGO;
466 break; 477 break;
467 case ISCSI_BOOT_ETH_SECONDARY_DNS: 478 case ISCSI_BOOT_ETH_SECONDARY_DNS:
468 if (memcmp(nic->secondary_dns, nulls, 479 if (address_not_null(nic->secondary_dns))
469 sizeof(nic->secondary_dns)))
470 rc = S_IRUGO; 480 rc = S_IRUGO;
471 break; 481 break;
472 case ISCSI_BOOT_ETH_DHCP: 482 case ISCSI_BOOT_ETH_DHCP:
473 if (memcmp(nic->dhcp, nulls, sizeof(nic->dhcp))) 483 if (address_not_null(nic->dhcp))
474 rc = S_IRUGO; 484 rc = S_IRUGO;
475 break; 485 break;
476 case ISCSI_BOOT_ETH_VLAN: 486 case ISCSI_BOOT_ETH_VLAN:
@@ -536,23 +546,19 @@ static umode_t __init ibft_check_initiator_for(void *data, int type)
536 rc = S_IRUGO; 546 rc = S_IRUGO;
537 break; 547 break;
538 case ISCSI_BOOT_INI_ISNS_SERVER: 548 case ISCSI_BOOT_INI_ISNS_SERVER:
539 if (memcmp(init->isns_server, nulls, 549 if (address_not_null(init->isns_server))
540 sizeof(init->isns_server)))
541 rc = S_IRUGO; 550 rc = S_IRUGO;
542 break; 551 break;
543 case ISCSI_BOOT_INI_SLP_SERVER: 552 case ISCSI_BOOT_INI_SLP_SERVER:
544 if (memcmp(init->slp_server, nulls, 553 if (address_not_null(init->slp_server))
545 sizeof(init->slp_server)))
546 rc = S_IRUGO; 554 rc = S_IRUGO;
547 break; 555 break;
548 case ISCSI_BOOT_INI_PRI_RADIUS_SERVER: 556 case ISCSI_BOOT_INI_PRI_RADIUS_SERVER:
549 if (memcmp(init->pri_radius_server, nulls, 557 if (address_not_null(init->pri_radius_server))
550 sizeof(init->pri_radius_server)))
551 rc = S_IRUGO; 558 rc = S_IRUGO;
552 break; 559 break;
553 case ISCSI_BOOT_INI_SEC_RADIUS_SERVER: 560 case ISCSI_BOOT_INI_SEC_RADIUS_SERVER:
554 if (memcmp(init->sec_radius_server, nulls, 561 if (address_not_null(init->sec_radius_server))
555 sizeof(init->sec_radius_server)))
556 rc = S_IRUGO; 562 rc = S_IRUGO;
557 break; 563 break;
558 case ISCSI_BOOT_INI_INITIATOR_NAME: 564 case ISCSI_BOOT_INI_INITIATOR_NAME: