[netperf-dev] netperf2 commit notice r368 - in trunk: . src

raj at netperf.org raj at netperf.org
Mon Nov 29 16:45:04 PST 2010


Author: raj
Date: 2010-11-29 16:45:04 -0800 (Mon, 29 Nov 2010)
New Revision: 368

Modified:
   trunk/Release_Notes
   trunk/src/netlib.c
   trunk/src/netlib.h
   trunk/src/netsh.c
   trunk/src/netsh.h
   trunk/src/nettest_omni.c
Log:
allow data connection IP address randomization in omni tests based on patch from google

Modified: trunk/Release_Notes
===================================================================
--- trunk/Release_Notes	2010-11-29 22:02:48 UTC (rev 367)
+++ trunk/Release_Notes	2010-11-30 00:45:04 UTC (rev 368)
@@ -1,5 +1,13 @@
 These are the Release Notes for post-revision 2.4.5 of netperf:
 
+*) WANT_MIGRATION is enabled when one specifies --enable-omni on the
+   configure command line.
+
+*) Massage and encorporate a patch from Google that enables randomization
+   of the IP addresses used in a test.  An optional mask length in the
+   standard '/' notation can be added to the end of the IP/name in the 
+   test-specific -H or -L options of an Omni test.
+
 *) Massage and include a DEBUG_LOG_FILE patch for Android from
    Josselin Costanzi
 

Modified: trunk/src/netlib.c
===================================================================
--- trunk/src/netlib.c	2010-11-29 22:02:48 UTC (rev 367)
+++ trunk/src/netlib.c	2010-11-30 00:45:04 UTC (rev 368)
@@ -29,8 +29,10 @@
 /*      format_units()          return the format in english    */
 /*      msec_sleep()            sleep for some msecs            */
 /*      start_timer()           start a timer                   */
+/*      random_ip_address()     select a random IP address from */
+/*                              specified range                 */
 /*                                                              */
-/*      the routines you get when WANT_DLPI is defined...         */
+/*      the routines you get when WANT_DLPI is defined...       */
 /*                                                              */
 /*      dl_open()               open a file descriptor and      */
 /*                              attach to the card              */
@@ -505,6 +507,7 @@
 
 
 
+
 char unknown[32];
 
 char *
@@ -706,8 +709,78 @@
   return(conv_rec.whole_thing);
   
 }
+
 
 
+unsigned long
+rand32(){
+  return (unsigned long)lrand48() * 2 + lrand48() % 2;
+}
+
+/* this routine will set the ip address of the sockaddr in the
+   addrinfo to a random number in range, based on the address
+   family. for grins, we will sanity check the value of mask_len
+   against the address family. initial version from google,
+   enhancements by raj 20101129 */
+void
+random_ip_address(struct addrinfo *res, int mask_len)
+{
+  switch(res->ai_family) {
+  case AF_INET: {
+    struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
+    unsigned int addr = ntohl(foo->sin_addr.s_addr);
+    unsigned long mask = ((unsigned long)1 << (32 - mask_len)) - 1;
+
+    if ((mask_len < 0) || (mask_len > 32)) {
+      fprintf(where,
+	      "Mask length must be between 0 and 32 inclusive for AF_INET\n");
+      fflush(where);
+      exit(-1);
+    }
+
+    addr = ntohl(foo->sin_addr.s_addr);
+    do {
+      addr = (addr & ~mask) | (rand32() & mask);
+    } while ((addr & 0xff) == 0xff);
+    foo->sin_addr.s_addr = htonl(addr);
+    break;
+  }
+#if defined(AF_INET6)
+  case AF_INET6: {
+    struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
+
+    unsigned int i, len;
+    unsigned int *addr = (unsigned int *)&(foo->sin6_addr.s6_addr);
+    unsigned long mask;
+
+    if ((mask_len < 0) || (mask_len > 128)) {
+      fprintf(where,
+	      "Mask length must be between 0 and 128 inclusive for AF_INET\n");
+      fflush(where);
+      exit(-1);
+    }
+    
+    for (i = 0; i < 4; i ++){
+      addr[i] = ntohl(addr[i]);
+      len = mask_len - i * 32;
+      len = ((len < 32) ? len : 32);
+      len = ((len > 0) ? len : 0);
+      mask = ((unsigned long)1 << (32 - len)) - 1;
+      addr[i] = (addr[i] & ~mask) | (rand32() & mask);
+      addr[i] = htonl(addr[i]);
+     }
+    break;
+  }
+#endif
+  default:
+    fprintf(where,
+            "Unexpected Address Family of %u\n",res->ai_family);
+    fflush(where);
+    exit(-1);
+  }
+}
+
+
 /* one of these days, this should be abstracted-out just like the CPU
    util stuff.  raj 2005-01-27 */
 int

Modified: trunk/src/netlib.h
===================================================================
--- trunk/src/netlib.h	2010-11-29 22:02:48 UTC (rev 367)
+++ trunk/src/netlib.h	2010-11-30 00:45:04 UTC (rev 368)
@@ -544,6 +544,7 @@
 extern  double  ntohd(double net_double);
 extern  double  htond(double host_double);
 extern  int     inet_nton(int af, const void *src, char *dst, int cnt);
+extern  void    random_ip_address(struct addrinfo *res, int mask_len);
 extern  void    libmain();
 extern  double  calc_thruput(double units_received);
 extern  double  calc_thruput_interval(double units_received,double elapsed);

Modified: trunk/src/netsh.c
===================================================================
--- trunk/src/netsh.c	2010-11-29 22:02:48 UTC (rev 367)
+++ trunk/src/netsh.c	2010-11-30 00:45:04 UTC (rev 368)
@@ -327,25 +327,26 @@
   while ((*arg1++ = *s++) != '\0');
 }
 
-/* break_args_explicit
+/* break_args_explicit_sep
 
    this routine is somewhat like break_args in that it will separate a
-   pair of comma-separated values.  however, if there is no comma,
-   this version will not ass-u-me that arg2 should be the same as
-   arg1. raj 2005-02-04 */
+   pair of values using the given separator.  however, if there is no
+   separator this version will not ass-u-me that arg2 should be the
+   same as arg1. raj 20101129 */
+
 void
-break_args_explicit(char *s, char *arg1, char *arg2)
+break_args_explicit_sep(char *s, int sep, char *arg1, char *arg2)
 
 {
   char *ns;
-  ns = strchr(s,',');
+  ns = strchr(s,sep);
   if (ns) {
-    /* there was a comma arg2 should be the second arg*/
+    /* there was a separator arg2 should be the second arg*/
     *ns++ = '\0';
     while ((*arg2++ = *ns++) != '\0');
   }
   else {
-    /* there was not a comma, so we should make sure that arg2 is \0
+    /* there was no separator, so we should make sure that arg2 is \0
        lest something become confused. raj 2005-02-04 */
     *arg2 = '\0';
   };
@@ -353,6 +354,18 @@
 
 }
 
+/* break_args_explicit - now just a wrapper around a call to
+   break_args_explicit_sep passing-in a ',' as the separator. raj
+   20101129 */ 
+
+void
+break_args_explicit(char *s, char *arg1, char *arg2)
+
+{
+  break_args_explicit_sep(s, ',', arg1, arg2);
+}
+
+
 /* given a string with possible values for setting an address family,
    convert that into one of the AF_mumble values - AF_INET, AF_INET6,
    AF_UNSPEC as apropriate. the family_string is compared in a

Modified: trunk/src/netsh.h
===================================================================
--- trunk/src/netsh.h	2010-11-29 22:02:48 UTC (rev 367)
+++ trunk/src/netsh.h	2010-11-30 00:45:04 UTC (rev 368)
@@ -78,6 +78,7 @@
 extern void     dump_globals();
 extern void     break_args(char *s, char *arg1, char *arg2);
 extern void     break_args_explicit(char *s, char *arg1, char *arg2);
+extern void     break_args_explicit_sep(char *s, int sep, char *arg1, char *arg2);
 extern void     print_netserver_usage();
 
 /* output controlling variables                                         */

Modified: trunk/src/nettest_omni.c
===================================================================
--- trunk/src/nettest_omni.c	2010-11-29 22:02:48 UTC (rev 367)
+++ trunk/src/nettest_omni.c	2010-11-30 00:45:04 UTC (rev 368)
@@ -458,6 +458,10 @@
    keep it because it won't be for other tests */
 double      mean_latency = -1.0, stddev_latency = -1.0;
 
+/* default to zero to avoid randomizing */
+int local_mask_len=0;
+int remote_mask_len=0;
+
 int printing_initialized = 0;
 
 char *sd_str;
@@ -4410,6 +4414,13 @@
     request_cwnd = REQUEST_CWND_INITIAL;
 #endif
 
+    /* if the command-line included requests to randomize the IP
+       addresses, then honor it.  of course, this may not work all that
+       well for some tests... raj 20101129 */
+    if (local_mask_len) 
+      random_ip_address(local_res, local_mask_len);
+    if (remote_mask_len)
+      random_ip_address(remote_res, remote_mask_len);
 
     data_socket = create_data_socket(local_res);
     
@@ -7341,13 +7352,71 @@
   socket_type_str = hst_to_str(socket_type);
 }
 
+char omni_usage[] = "\n\
+Usage: netperf [global options] -- [test options] \n\
+\n\
+OMNI and Migrated BSD Sockets Test Options:\n\
+    -b number         Send number requests at start of _RR tests\n\
+    -c                Explicitly declare this a connection test such as\n\
+                      TCP_CRR or TCP_CC\n\
+    -C                Set TCP_CORK when available\n\
+    -d direction      Explicitly set test direction based on bitwise OR\n\
+                      of 0x2 for transmit and 0x4 for receive. Default:\n\
+                      based on test type\n\
+    -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
+    -h                Display this text\n\
+    -H name[/mask],fam  Use name (or IP) and family as target of data connection\n\
+                      A mask value will cause randomization of the IP used\n\
+    -k [file]         Generate keyval output optionally based on file\n\
+                      Use filename of '?' to get the list of choices\n\
+    -L name[/mask],fam  Use name (or IP) and family as source of data connection\n\
+                      A mask value will cause randomization of the IP used\n\
+    -m bytes          Set the send size (TCP_STREAM, UDP_STREAM)\n\
+    -M bytes          Set the recv size (TCP_STREAM, UDP_STREAM)\n\
+    -n                Use the connected socket for UDP locally\n\
+    -N                Use the connected socket for UDP remotely\n\
+    -o [file]         Generate CSV output optionally based on file\n\
+                      Use filename of '?' to get the list of choices\n\
+    -O [file]         Generate classic-style output based on file\n\
+                      Use filename of '?' to get the list of choices\n\
+    -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
+    -P local[,remote] Set the local/remote port for the data socket\n\
+    -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
+    -R 0/1            Allow routing of traffic on data connection.\n\
+                      Default: 0 (off) for UDP_STREAM, 1 (on) otherwise\n\
+    -s send[,recv]    Set local socket send/recv buffer sizes\n\
+    -S send[,recv]    Set remote socket send/recv buffer sizes\n\
+    -t type           Explicitly set socket type. Default is implicit\n\
+                      based on other settings\n\
+    -T protocol       Explicitly set data connection protocol. Default is\n\
+                      implicit based on other settings\n\
+    -u uuid           Use the supplied string as the UUID for this test.\n\
+    -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
+    -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
+\n\
+For those options taking two parms, at least one must be specified;\n\
+specifying one value without a comma will set both parms to that\n\
+value, specifying a value with a leading comma will set just the second\n\
+parm, a value with a trailing comma will set just the first. To set\n\
+each parm to unique values, specify both and separate them with a\n\
+comma.\n"; 
+
+void
+print_omni_usage()
+{
+
+  fwrite(omni_usage, sizeof(char), strlen(omni_usage), stdout);
+  exit(1);
+
+}
+
 
 void
 scan_omni_args(int argc, char *argv[])
 
 {
 
-#define OMNI_ARGS "b:cCd:DnNhH:kl:L:m:M:oOp:P:r:R:s:S:t:T:u:Vw:W:46"
+#define OMNI_ARGS "b:cCd:DhH:kl:L:m:M:nNoOp:P:r:R:s:S:t:T:u:Vw:W:46"
 
   extern char	*optarg;	  /* pointer to option string	*/
   
@@ -7357,7 +7426,8 @@
 
   char	
     arg1[BUFSIZ],  /* argument holders		*/
-    arg2[BUFSIZ];
+    arg2[BUFSIZ],
+    arg3[BUFSIZ];
 
   if (debug) {
     int i;
@@ -7400,7 +7470,7 @@
 #endif
       break;
     case 'h':
-      print_sockets_usage();
+      print_omni_usage();
       exit(1);
     case 'b':
 #ifdef WANT_FIRST_BURST
@@ -7432,15 +7502,25 @@
       rem_nodelay = 1;
       break;
     case 'H':
-      break_args_explicit(optarg,arg1,arg2);
+      break_args_explicit_sep(optarg,',',arg1,arg2);
       if (arg1[0]) {
-	/* make sure we leave room for the NULL termination boys and
-	   girls. raj 2005-02-82 */ 
-	remote_data_address = malloc(strlen(arg1)+1);
-	strcpy(remote_data_address,arg1);
+	/* check to see if there was a width, which we would want to
+	   be arg3. for simplicities sake, we will assume the width
+	   must follow the address and not the address family - ie
+	   1.2.3.4/24,inet.  This means we can just pass optarg again
+	   as the source rather than have to shuffle arg values. */ 
+	break_args_explicit_sep(optarg,'/',arg1,arg3);
+	if (arg1[0]) {
+	  remote_data_address = malloc(strlen(arg1)+1);
+	  strcpy(remote_data_address,arg1);
+	}
+	if (arg3[0]) {
+	  remote_mask_len = convert(arg3);
+	}
       }
-      if (arg2[0])
+      if (arg2[0]) {
 	remote_data_family = parse_address_family(arg2);
+      }
       break;
     case 'k':
       human = 0;
@@ -7473,15 +7553,25 @@
       multicast_ttl = atoi(optarg);
       break;
     case 'L':
-      break_args_explicit(optarg,arg1,arg2);
+      break_args_explicit_sep(optarg,',',arg1,arg2);
       if (arg1[0]) {
-	/* make sure we leave room for the NULL termination boys and
-	   girls. raj 2005-02-82 */ 
-	local_data_address = malloc(strlen(arg1)+1);
-	strcpy(local_data_address,arg1);
+	/* check to see if there was a width, which we would want to
+	   be arg3. for simplicities sake, we will assume the width
+	   must follow the address and not the address family - ie
+	   1.2.3.4/24,inet.  This means we can just pass optarg again
+	   as the source rather than have to shuffle arg values. */ 
+	break_args_explicit_sep(optarg,'/',arg1,arg3);
+	if (arg1[0]) {
+	  local_data_address = malloc(strlen(arg1)+1);
+	  strcpy(local_data_address,arg1);
+	}
+	if (arg3[0]) {
+	  local_mask_len = convert(arg3);
+	}
       }
-      if (arg2[0])
+      if (arg2[0]) {
 	local_data_family = parse_address_family(arg2);
+      }
       break;
     case 'm':
       /* set the send size. if we set the local send size it will add



More information about the netperf-dev mailing list