Hello,
is there any way (or will be) to adjust pps using TX_RING? I want to 
specify larger values, i.e. 5 million pps .. and that's impossible with 1 
CPU.

Thanks.

Dňa pondelok, 21. decembra 2015 0:17:13 UTC+1 Vadim Kochan napísal(-a):
>
> Added -b,--rate option in units of: 
>
>     pps/B/KB/MB/kBit/Mbit/Gbit/KiB/MiB/GiB 
>
> to specify rate at which packets will be sent. 
> Similary to -t,--gap option the packets will be sent 
> in slow mode with 1 CPU. 
>
> Signed-off-by: Vadim Kochan <[email protected] <javascript:>> 
> --- 
>  trafgen.8 |   4 ++ 
>  trafgen.c | 138 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 
>  2 files changed, 133 insertions(+), 9 deletions(-) 
>
> diff --git a/trafgen.8 b/trafgen.8 
> index 6f5d318..c78a373 100644 
> --- a/trafgen.8 
> +++ b/trafgen.8 
> @@ -136,6 +136,10 @@ probing for a given interval, iii) ping-like 
> debugging with specific payload 
>  patterns. Furthermore, the TX_RING interface does not cope with 
> interpacket 
>  gaps. 
>  .PP 
> +.SS -b <rate>, --rate <rate> 
> +Specify the rate of packet sending in 
> <num>pps/B/KB/MB/GB/kBit/Mbit/Gbit/KiB/MiB/GiB units. 
> +Similary to -t,--gap option - packets are sent in slow mode. 
> +.PP 
>  .SS -S <size>, --ring-size <size> 
>  Manually define the TX_RING resp. TX_RING size in ''<num>KiB/MiB/GiB''. 
> On 
>  default the size is being determined based on the network connectivity 
> rate. 
> diff --git a/trafgen.c b/trafgen.c 
> index df2ecf4..969b8b7 100644 
> --- a/trafgen.c 
> +++ b/trafgen.c 
> @@ -55,6 +55,26 @@ 
>  #include "ring_tx.h" 
>  #include "csum.h" 
>   
> +#ifndef timeval_to_timespec 
> +#define timeval_to_timespec(tv, ts) {         \ 
> +        (ts)->tv_sec = (tv)->tv_sec;          \ 
> +        (ts)->tv_nsec = (tv)->tv_usec * 1000; \ 
> +} 
> +#endif 
> + 
> +enum shaper_type { 
> +        SHAPER_PKTS, 
> +        SHAPER_BYTES, 
> +}; 
> + 
> +struct shaper { 
> +        enum shaper_type type; 
> +        unsigned long rate; 
> +        unsigned long long sent; 
> +        struct timeval start; 
> +        struct timeval end; 
> +}; 
> + 
>  struct ctx { 
>          bool rand, rfraw, jumbo_support, verbose, smoke_test, enforce, 
> qdisc_path; 
>          size_t reserve_size; 
> @@ -65,6 +85,7 @@ struct ctx { 
>          struct timespec gap; 
>          struct sockaddr_in dest; 
>          char *packet_str; 
> +        struct shaper sh; 
>  }; 
>   
>  struct cpu_stats { 
> @@ -83,7 +104,7 @@ size_t plen = 0; 
>  struct packet_dyn *packet_dyn = NULL; 
>  size_t dlen = 0; 
>   
> -static const char *short_options = 
> "d:c:n:t:vJhS:rk:i:o:VRs:P:eE:pu:g:CHQqD:"; 
> +static const char *short_options = 
> "d:c:n:t:vJhS:rk:i:o:VRs:P:eE:pu:g:CHQqD:b:"; 
>  static const struct option long_options[] = { 
>          {"dev",                        required_argument,        NULL, 
> 'd'}, 
>          {"out",                        required_argument,        NULL, 
> 'o'}, 
> @@ -91,6 +112,7 @@ static const struct option long_options[] = { 
>          {"conf",                required_argument,        NULL, 'c'}, 
>          {"num",                        required_argument,        NULL, 
> 'n'}, 
>          {"gap",                        required_argument,        NULL, 
> 't'}, 
> +        {"rate",                required_argument,        NULL, 'b'}, 
>          {"cpus",                required_argument,        NULL, 'P'}, 
>          {"ring-size",                required_argument,        NULL, 
> 'S'}, 
>          {"kernel-pull",                required_argument,        NULL, 
> 'k'}, 
> @@ -172,6 +194,7 @@ static void __noreturn help(void) 
>               "  -r|--rand                      Randomize packet selection 
> (def: round robin)\n" 
>               "  -P|--cpus <uint>               Specify number of forks(<= 
> CPUs) (def: #CPUs)\n" 
>               "  -t|--gap <time>                Set approx. interpacket 
> gap (s/ms/us/ns, def: us)\n" 
> +             "  -b|--rate <rate>               Send traffic at specified 
> rate (pps/B/KB/MB/GB/kBit/Mbit/Gbit/KiB/MiB/GiB)\n" 
>               "  -S|--ring-size <size>          Manually set mmap size 
> (KiB/MiB/GiB)\n" 
>               "  -E|--seed <uint>               Manually set srand(3) 
> seed\n" 
>               "  -u|--user <userid>             Drop privileges and change 
> to userid\n" 
> @@ -535,6 +558,51 @@ static int xmit_smoke_probe(int icmp_sock, struct ctx 
> *ctx) 
>          return -1; 
>  } 
>   
> +static bool shaper_is_set(struct shaper *sh) 
> +{ 
> +        return sh->rate != 0; 
> +} 
> + 
> +static void shaper_start(struct shaper *sh) 
> +{ 
> +        bug_on(gettimeofday(&sh->start, NULL)); 
> +        sh->sent = 0; 
> +} 
> + 
> +static void shaper_init(struct shaper *sh, unsigned long rate, enum 
> shaper_type type) 
> +{ 
> +        memset(sh, 0, sizeof(struct shaper)); 
> +        sh->rate = rate; 
> +        sh->type = type; 
> +} 
> + 
> +static void shaper_delay(struct shaper *sh, unsigned long long pkt_len) 
> +{ 
> +        if ((sh->start.tv_sec | sh->start.tv_usec) > 0) { 
> +                sh->sent += sh->type == SHAPER_BYTES ? pkt_len : 1; 
> + 
> +                if (sh->sent >= sh->rate) { 
> +                        struct timeval delay_us; 
> +                        struct timespec delay_ns; 
> +                        struct timeval time_sent; 
> +                        struct timeval time_1s = { .tv_sec = 1 }; 
> + 
> +                        bug_on(gettimeofday(&sh->end, NULL)); 
> +                        timersub(&sh->end, &sh->start, &time_sent); 
> + 
> +                        if (timercmp(&time_1s, &time_sent, > )) { 
> +                                timersub(&time_1s, &time_sent, 
> &delay_us); 
> +                                timeval_to_timespec(&delay_us, 
> &delay_ns); 
> + 
> +                                if ((delay_ns.tv_sec | delay_ns.tv_nsec) 
> > 0) 
> +                                        nanosleep(&delay_ns, NULL); 
> +                        } 
> + 
> +                        shaper_start(sh); 
> +                } 
> +        } 
> +} 
> + 
>  static void xmit_slowpath_or_die(struct ctx *ctx, unsigned int cpu, 
> unsigned long orig_num) 
>  { 
>          int ret, icmp_sock = -1; 
> @@ -560,6 +628,9 @@ static void xmit_slowpath_or_die(struct ctx *ctx, 
> unsigned int cpu, unsigned lon 
>   
>          bug_on(gettimeofday(&start, NULL)); 
>   
> +        if (shaper_is_set(&ctx->sh)) 
> +                shaper_start(&ctx->sh); 
> + 
>          while (likely(sigint == 0 && num > 0 && plen > 0)) { 
>                  pktd = &packet_dyn[i]; 
>                  if (packet_dyn_has_elems(pktd)) { 
> @@ -605,6 +676,9 @@ retry: 
>                  if (ctx->num > 0) 
>                          num--; 
>   
> +                if (shaper_is_set(&ctx->sh)) 
> +                        shaper_delay(&ctx->sh, packets[i].len); 
> + 
>                  if ((ctx->gap.tv_sec | ctx->gap.tv_nsec) > 0) 
>                          nanosleep(&ctx->gap, NULL); 
>          } 
> @@ -901,6 +975,8 @@ int main(int argc, char **argv) 
>          int min_opts = 5; 
>          char **cpp_argv = NULL; 
>          size_t cpp_argc = 0; 
> +        unsigned long rate; 
> +        enum shaper_type shape_type; 
>   
>          fmemset(&ctx, 0, sizeof(ctx)); 
>          ctx.cpus = get_number_cpus_online(); 
> @@ -999,9 +1075,7 @@ int main(int argc, char **argv) 
>                          ctx.num = orig_num; 
>                          break; 
>                  case 't': 
> -                        slow = true; 
>                          ptr = optarg; 
> -                        prctl(PR_SET_TIMERSLACK, 1UL); 
>                          gap = strtoul(optarg, NULL, 0); 
>   
>                          for (j = i = strlen(optarg); i > 0; --i) { 
> @@ -1025,14 +1099,51 @@ int main(int argc, char **argv) 
>                          } else if (!strncmp(ptr, "s", strlen("s"))) { 
>                                  ctx.gap.tv_sec = gap; 
>                                  ctx.gap.tv_nsec = 0; 
> -                        } else 
> +                        } else { 
>                                  panic("Syntax error in time param!\n"); 
> +                        } 
> +                        break; 
> +                case 'b': 
> +                        rate = strtoul(optarg, &ptr, 0); 
> +                        if (!rate || optarg == ptr) 
> +                                panic("Invalid rate param\n"); 
> + 
> +                        if (strncmp(ptr, "pps", strlen("pps")) == 0) { 
> +                                shape_type = SHAPER_PKTS; 
> +                        } else if (strncmp(ptr, "B", strlen("B")) == 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                        } else if (strncmp(ptr, "kB", strlen("KB")) == 0) 
> { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1000; 
> +                        } else if (strncmp(ptr, "MB", strlen("MB")) == 0) 
> { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1000 * 1000; 
> +                        } else if (strncmp(ptr, "GB", strlen("GB")) == 0) 
> { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1000 * 1000 * 1000; 
> +                        } else if (strncmp(ptr, "kbit", strlen("kbit")) 
> == 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1000 / 8; 
> +                        } else if (strncmp(ptr, "Mbit", strlen("Mbit")) 
> == 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1000 * 1000 / 8; 
> +                        } else if (strncmp(ptr, "Gbit", strlen("Gbit")) 
> == 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1000 * 1000 * 1000 / 8; 
> +                        } else if (strncmp(ptr, "KiB", strlen("KiB")) == 
> 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1 << 10; 
> +                        } else if (strncmp(ptr, "MiB", strlen("MiB")) == 
> 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1 << 20; 
> +                        } else if (strncmp(ptr, "GiB", strlen("GiB")) == 
> 0) { 
> +                                shape_type = SHAPER_BYTES; 
> +                                rate *= 1 << 30; 
> +                        } else { 
> +                                panic("Invalid unit type for rate\n"); 
> +                        } 
>   
> -                        if (gap > 0) 
> -                                /* Fall back to single core to not mess 
> up 
> -                                 * correct timing. We are slow anyway! 
> -                                 */ 
> -                                ctx.cpus = 1; 
> +                        shaper_init(&ctx.sh, rate, shape_type); 
>                          break; 
>                  case 'S': 
>                          ptr = optarg; 
> @@ -1118,6 +1229,15 @@ int main(int argc, char **argv) 
>                  sleep(0); 
>          } 
>   
> +        if (shaper_is_set(&ctx.sh) || (ctx.gap.tv_sec | ctx.gap.tv_nsec) 
> > 0) { 
> +                prctl(PR_SET_TIMERSLACK, 1UL); 
> +                /* Fall back to single core to not mess up correct 
> timing. 
> +                 * We are slow anyway! 
> +                 */ 
> +                ctx.cpus = 1; 
> +                slow = true; 
> +        } 
> + 
>          /* 
>           * If number of packets is smaller than number of CPUs use only 
> as 
>           * many CPUs as there are packets. Otherwise we end up sending 
> more 
> -- 
> 2.6.3 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to