aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-08-16 21:32:17 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-17 11:23:58 -0400
commit6a60a6a8ea97795a288469c21262522894a1e6db (patch)
treed51f0e970221137502beb00146aaf2575e75dac2 /tools
parent04405784591117539eac4f5348c86d66dc0dd4f1 (diff)
Tools: hv: Represent the ipv6 mask using CIDR notation
Transform ipv6 subnet information to CIDR notation. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/hv_kvp_daemon.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index de1724cbaf5..a63e83a0159 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -491,6 +491,15 @@ done:
491 return; 491 return;
492} 492}
493 493
494static unsigned int hweight32(unsigned int *w)
495{
496 unsigned int res = *w - ((*w >> 1) & 0x55555555);
497 res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
498 res = (res + (res >> 4)) & 0x0F0F0F0F;
499 res = res + (res >> 8);
500 return (res + (res >> 16)) & 0x000000FF;
501}
502
494static int kvp_process_ip_address(void *addrp, 503static int kvp_process_ip_address(void *addrp,
495 int family, char *buffer, 504 int family, char *buffer,
496 int length, int *offset) 505 int length, int *offset)
@@ -535,10 +544,15 @@ kvp_get_ip_address(int family, char *if_name, int op,
535 struct ifaddrs *curp; 544 struct ifaddrs *curp;
536 int offset = 0; 545 int offset = 0;
537 int sn_offset = 0; 546 int sn_offset = 0;
538 const char *str;
539 int error = 0; 547 int error = 0;
540 char *buffer; 548 char *buffer;
541 struct hv_kvp_ipaddr_value *ip_buffer; 549 struct hv_kvp_ipaddr_value *ip_buffer;
550 char cidr_mask[5]; /* /xyz */
551 int weight;
552 int i;
553 unsigned int *w;
554 char *sn_str;
555 struct sockaddr_in6 *addr6;
542 556
543 if (op == KVP_OP_ENUMERATE) { 557 if (op == KVP_OP_ENUMERATE) {
544 buffer = out_buffer; 558 buffer = out_buffer;
@@ -611,18 +625,30 @@ kvp_get_ip_address(int family, char *if_name, int op,
611 goto gather_ipaddr; 625 goto gather_ipaddr;
612 } else { 626 } else {
613 ip_buffer->addr_family |= ADDR_FAMILY_IPV6; 627 ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
628
614 /* 629 /*
615 * Get subnet info. 630 * Get subnet info in CIDR format.
616 */ 631 */
617 error = kvp_process_ip_address( 632 weight = 0;
618 curp->ifa_netmask, 633 sn_str = (char *)ip_buffer->sub_net;
619 AF_INET6, 634 addr6 = (struct sockaddr_in6 *)
620 (char *) 635 curp->ifa_netmask;
621 ip_buffer->sub_net, 636 w = addr6->sin6_addr.s6_addr32;
622 length, 637
623 &sn_offset); 638 for (i = 0; i < 4; i++)
624 if (error) 639 weight += hweight32(&w[i]);
640
641 sprintf(cidr_mask, "/%d", weight);
642 if ((length - sn_offset) <
643 (strlen(cidr_mask) + 1))
625 goto gather_ipaddr; 644 goto gather_ipaddr;
645
646 if (sn_offset == 0)
647 strcpy(sn_str, cidr_mask);
648 else
649 strcat(sn_str, cidr_mask);
650 strcat((char *)ip_buffer->sub_net, ";");
651 sn_offset += strlen(sn_str) + 1;
626 } 652 }
627 } 653 }
628 654