Skip to content

Commit 4ba6341

Browse files
haiyangzgregkh
authored andcommitted
tools/hv: Fix IP reporting by KVP daemon with SRIOV
On Hyper-V the VF NIC has the same MAC as the related synthetic NIC. VF NIC can work under the synthetic NIC transparently, without its own IP address. The existing KVP daemon only gets IP from the first NIC matching a MAC address, and may not be able to find the IP in this case. This patch fixes the problem by searching the NIC matching the MAC, and having an IP address. So, the IP address will be found and reported to the host successfully. Signed-off-by: Haiyang Zhang <[email protected]> Signed-off-by: K. Y. Srinivasan <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 661e50b commit 4ba6341

File tree

1 file changed

+65
-73
lines changed

1 file changed

+65
-73
lines changed

tools/hv/hv_kvp_daemon.c

Lines changed: 65 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -634,64 +634,6 @@ static char *kvp_if_name_to_mac(char *if_name)
634634
return mac_addr;
635635
}
636636

637-
638-
/*
639-
* Retrieve the interface name given tha MAC address.
640-
*/
641-
642-
static char *kvp_mac_to_if_name(char *mac)
643-
{
644-
DIR *dir;
645-
struct dirent *entry;
646-
FILE *file;
647-
char *p, *x;
648-
char *if_name = NULL;
649-
char buf[256];
650-
char dev_id[PATH_MAX];
651-
unsigned int i;
652-
653-
dir = opendir(KVP_NET_DIR);
654-
if (dir == NULL)
655-
return NULL;
656-
657-
while ((entry = readdir(dir)) != NULL) {
658-
/*
659-
* Set the state for the next pass.
660-
*/
661-
snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR,
662-
entry->d_name);
663-
664-
file = fopen(dev_id, "r");
665-
if (file == NULL)
666-
continue;
667-
668-
p = fgets(buf, sizeof(buf), file);
669-
if (p) {
670-
x = strchr(p, '\n');
671-
if (x)
672-
*x = '\0';
673-
674-
for (i = 0; i < strlen(p); i++)
675-
p[i] = toupper(p[i]);
676-
677-
if (!strcmp(p, mac)) {
678-
/*
679-
* Found the MAC match; return the interface
680-
* name. The caller will free the memory.
681-
*/
682-
if_name = strdup(entry->d_name);
683-
fclose(file);
684-
break;
685-
}
686-
}
687-
fclose(file);
688-
}
689-
690-
closedir(dir);
691-
return if_name;
692-
}
693-
694-
695637
static void kvp_process_ipconfig_file(char *cmd,
696638
char *config_buf, unsigned int len,
697639
int element_size, int offset)
@@ -997,6 +939,70 @@ kvp_get_ip_info(int family, char *if_name, int op,
997939
return error;
998940
}
999941

942+
/*
943+
* Retrieve the IP given the MAC address.
944+
*/
945+
static int kvp_mac_to_ip(struct hv_kvp_ipaddr_value *kvp_ip_val)
946+
{
947+
char *mac = (char *)kvp_ip_val->adapter_id;
948+
DIR *dir;
949+
struct dirent *entry;
950+
FILE *file;
951+
char *p, *x;
952+
char *if_name = NULL;
953+
char buf[256];
954+
char dev_id[PATH_MAX];
955+
unsigned int i;
956+
int error = HV_E_FAIL;
957+
958+
dir = opendir(KVP_NET_DIR);
959+
if (dir == NULL)
960+
return HV_E_FAIL;
961+
962+
while ((entry = readdir(dir)) != NULL) {
963+
/*
964+
* Set the state for the next pass.
965+
*/
966+
snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR,
967+
entry->d_name);
968+
969+
file = fopen(dev_id, "r");
970+
if (file == NULL)
971+
continue;
972+
973+
p = fgets(buf, sizeof(buf), file);
974+
fclose(file);
975+
if (!p)
976+
continue;
977+
978+
x = strchr(p, '\n');
979+
if (x)
980+
*x = '\0';
981+
982+
for (i = 0; i < strlen(p); i++)
983+
p[i] = toupper(p[i]);
984+
985+
if (strcmp(p, mac))
986+
continue;
987+
988+
/*
989+
* Found the MAC match.
990+
* A NIC (e.g. VF) matching the MAC, but without IP, is skipped.
991+
*/
992+
if_name = entry->d_name;
993+
if (!if_name)
994+
continue;
995+
996+
error = kvp_get_ip_info(0, if_name, KVP_OP_GET_IP_INFO,
997+
kvp_ip_val, MAX_IP_ADDR_SIZE * 2);
998+
999+
if (!error && strlen((char *)kvp_ip_val->ip_addr))
1000+
break;
1001+
}
1002+
1003+
closedir(dir);
1004+
return error;
1005+
}
10001006

10011007
static int expand_ipv6(char *addr, int type)
10021008
{
@@ -1472,26 +1478,12 @@ int main(int argc, char *argv[])
14721478
switch (op) {
14731479
case KVP_OP_GET_IP_INFO:
14741480
kvp_ip_val = &hv_msg->body.kvp_ip_val;
1475-
if_name =
1476-
kvp_mac_to_if_name((char *)kvp_ip_val->adapter_id);
14771481

1478-
if (if_name == NULL) {
1479-
/*
1480-
* We could not map the mac address to an
1481-
* interface name; return error.
1482-
*/
1483-
hv_msg->error = HV_E_FAIL;
1484-
break;
1485-
}
1486-
error = kvp_get_ip_info(
1487-
0, if_name, KVP_OP_GET_IP_INFO,
1488-
kvp_ip_val,
1489-
(MAX_IP_ADDR_SIZE * 2));
1482+
error = kvp_mac_to_ip(kvp_ip_val);
14901483

14911484
if (error)
14921485
hv_msg->error = error;
14931486

1494-
free(if_name);
14951487
break;
14961488

14971489
case KVP_OP_SET_IP_INFO:

0 commit comments

Comments
 (0)