TAS
TCP Acceleration as an OS Service
config.c
1 /*
2  * Copyright 2019 University of Washington, Max Planck Institute for
3  * Software Systems, and The University of Texas at Austin
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <getopt.h>
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 #include <utils.h>
34 
35 #include <config.h>
36 
37 enum cfg_params {
38  CP_SHM_LEN,
39  CP_NIC_RX_LEN,
40  CP_NIC_TX_LEN,
41  CP_APP_KIN_LEN,
42  CP_APP_KOUT_LEN,
43  CP_ARP_TO,
44  CP_ARP_TO_MAX,
45  CP_TCP_RTT_INIT,
46  CP_TCP_LINK_BW,
47  CP_TCP_RXBUF_LEN,
48  CP_TCP_TXBUF_LEN,
49  CP_TCP_HANDSHAKE_TO,
50  CP_TCP_HANDSHAKE_RETRIES,
51  CP_CC,
52  CP_CC_CONTROL_GRANULARITY,
53  CP_CC_CONTROL_INTERVAL,
54  CP_CC_REXMIT_INTS,
55  CP_CC_DCTCP_WEIGHT,
56  CP_CC_DCTCP_INIT,
57  CP_CC_DCTCP_STEP,
58  CP_CC_DCTCP_MIMD,
59  CP_CC_DCTCP_MIN,
60  CP_CC_DCTCP_MINPKTS,
61  CP_CC_CONST_RATE,
62  CP_CC_TIMELY_TLOW,
63  CP_CC_TIMELY_THIGH,
64  CP_CC_TIMELY_STEP,
65  CP_CC_TIMELY_INIT,
66  CP_CC_TIMELY_ALPHA,
67  CP_CC_TIMELY_BETA,
68  CP_CC_TIMELY_MINRTT,
69  CP_CC_TIMELY_MINRATE,
70  CP_IP_ROUTE,
71  CP_IP_ADDR,
72  CP_FP_CORES_MAX,
73  CP_FP_NO_INTS,
74  CP_FP_NO_XSUMOFFLOAD,
75  CP_FP_NO_AUTOSCALE,
76  CP_FP_NO_HUGEPAGES,
77  CP_FP_VLAN_STRIP,
78  CP_FP_POLL_INTERVAL_TAS,
79  CP_FP_POLL_INTERVAL_APP,
80  CP_KNI_NAME,
81  CP_READY_FD,
82  CP_DPDK_EXTRA,
83  CP_QUIET,
84 };
85 
86 static struct option opts[] = {
87  { .name = "shm-len",
88  .has_arg = required_argument,
89  .val = CP_SHM_LEN },
90  { .name = "nic-rx-len",
91  .has_arg = required_argument,
92  .val = CP_NIC_RX_LEN },
93  { .name = "nic-tx-len",
94  .has_arg = required_argument,
95  .val = CP_NIC_TX_LEN },
96  { .name = "app-kin-len",
97  .has_arg = required_argument,
98  .val = CP_APP_KIN_LEN },
99  { .name = "app-kout-len",
100  .has_arg = required_argument,
101  .val = CP_APP_KOUT_LEN },
102  { .name = "arp-timout",
103  .has_arg = required_argument,
104  .val = CP_ARP_TO },
105  { .name = "arp-timeout-max",
106  .has_arg = required_argument,
107  .val = CP_ARP_TO },
108  { .name = "tcp-rtt-init",
109  .has_arg = required_argument,
110  .val = CP_TCP_RTT_INIT },
111  { .name = "tcp-link-bw",
112  .has_arg = required_argument,
113  .val = CP_TCP_LINK_BW },
114  { .name = "tcp-rxbuf-len",
115  .has_arg = required_argument,
116  .val = CP_TCP_RXBUF_LEN },
117  { .name = "tcp-txbuf-len",
118  .has_arg = required_argument,
119  .val = CP_TCP_TXBUF_LEN },
120  { .name = "tcp-handshake-timeout",
121  .has_arg = required_argument,
122  .val = CP_TCP_HANDSHAKE_TO },
123  { .name = "tcp-handshake-retries",
124  .has_arg = required_argument,
125  .val = CP_TCP_HANDSHAKE_RETRIES },
126  { .name = "cc",
127  .has_arg = required_argument,
128  .val = CP_CC },
129  { .name = "cc-control-granularity",
130  .has_arg = required_argument,
131  .val = CP_CC_CONTROL_GRANULARITY },
132  { .name = "cc-control-interval",
133  .has_arg = required_argument,
134  .val = CP_CC_CONTROL_INTERVAL },
135  { .name = "cc-rexmit-ints",
136  .has_arg = required_argument,
137  .val = CP_CC_REXMIT_INTS },
138  { .name = "cc-dctcp-weight",
139  .has_arg = required_argument,
140  .val = CP_CC_DCTCP_WEIGHT },
141  { .name = "cc-dctcp-init",
142  .has_arg = required_argument,
143  .val = CP_CC_DCTCP_INIT },
144  { .name = "cc-dctcp-step",
145  .has_arg = required_argument,
146  .val = CP_CC_DCTCP_STEP },
147  { .name = "cc-dctcp-mimd",
148  .has_arg = required_argument,
149  .val = CP_CC_DCTCP_MIMD },
150  { .name = "cc-dctcp-min",
151  .has_arg = required_argument,
152  .val = CP_CC_DCTCP_MIN },
153  { .name = "cc-dctcp-minpkts",
154  .has_arg = required_argument,
155  .val = CP_CC_DCTCP_MINPKTS },
156  { .name = "cc-const-rate",
157  .has_arg = required_argument,
158  .val = CP_CC_CONST_RATE },
159  { .name = "cc-timely-tlow",
160  .has_arg = required_argument,
161  .val = CP_CC_TIMELY_TLOW },
162  { .name = "cc-timely-thigh",
163  .has_arg = required_argument,
164  .val = CP_CC_TIMELY_THIGH },
165  { .name = "cc-timely-step",
166  .has_arg = required_argument,
167  .val = CP_CC_TIMELY_STEP },
168  { .name = "cc-timely-init",
169  .has_arg = required_argument,
170  .val = CP_CC_TIMELY_INIT },
171  { .name = "cc-timely-alpha",
172  .has_arg = required_argument,
173  .val = CP_CC_TIMELY_ALPHA },
174  { .name = "cc-timely-beta",
175  .has_arg = required_argument,
176  .val = CP_CC_TIMELY_BETA },
177  { .name = "cc-timely-minrtt",
178  .has_arg = required_argument,
179  .val = CP_CC_TIMELY_MINRTT },
180  { .name = "cc-timely-minrate",
181  .has_arg = required_argument,
182  .val = CP_CC_TIMELY_MINRATE },
183  { .name = "ip-route",
184  .has_arg = required_argument,
185  .val = CP_IP_ROUTE },
186  { .name = "ip-addr",
187  .has_arg = required_argument,
188  .val = CP_IP_ADDR },
189  { .name = "fp-cores-max",
190  .has_arg = required_argument,
191  .val = CP_FP_CORES_MAX },
192  { .name = "fp-no-ints",
193  .has_arg = no_argument,
194  .val = CP_FP_NO_INTS },
195  { .name = "fp-no-xsumoffload",
196  .has_arg = no_argument,
197  .val = CP_FP_NO_XSUMOFFLOAD },
198  { .name = "fp-no-autoscale",
199  .has_arg = no_argument,
200  .val = CP_FP_NO_AUTOSCALE },
201  { .name = "fp-no-hugepages",
202  .has_arg = no_argument,
203  .val = CP_FP_NO_HUGEPAGES },
204  { .name = "fp-vlan-strip",
205  .has_arg = no_argument,
206  .val = CP_FP_VLAN_STRIP },
207  { .name = "fp-poll-interval-tas",
208  .has_arg = required_argument,
209  .val = CP_FP_POLL_INTERVAL_TAS },
210  { .name = "fp-poll-interval-app",
211  .has_arg = required_argument,
212  .val = CP_FP_POLL_INTERVAL_APP },
213  { .name = "kni-name",
214  .has_arg = required_argument,
215  .val = CP_KNI_NAME },
216  { .name = "ready-fd",
217  .has_arg = required_argument,
218  .val = CP_READY_FD },
219  { .name = "dpdk-extra",
220  .has_arg = required_argument,
221  .val = CP_DPDK_EXTRA },
222  { .name = "quiet",
223  .has_arg = no_argument,
224  .val = CP_QUIET },
225  { .name = NULL },
226  };
227 
228 static int config_defaults(struct configuration *c, char *progname);
229 static void print_usage(struct configuration *c, char *progname);
230 static inline int parse_int64(const char *s, uint64_t *pu64);
231 static inline int parse_int32(const char *s, uint32_t *pu32);
232 static inline int parse_int8(const char *s, uint8_t *pu8);
233 static inline int parse_double(const char *s, double *pd);
234 static inline int parse_cidr(char *s, uint32_t *ip, uint8_t *prefix);
235 static inline int parse_route(char *s, struct configuration *c);
236 static inline int parse_arg_append(char *s, struct configuration *c);
237 
238 int config_parse(struct configuration *c, int argc, char *argv[])
239 {
240  int ret, done = 0;
241  double d;
242  uint32_t i;
243 
244  if (config_defaults(c, argv[0]) != 0) {
245  fprintf(stderr, "config_parse: config defaults failed\n");
246  goto failed;
247  }
248 
249  while (!done) {
250  ret = getopt_long(argc, argv, "", opts, NULL);
251  switch (ret) {
252  case CP_SHM_LEN:
253  if (parse_int64(optarg, &c->shm_len) != 0) {
254  fprintf(stderr, "shm len parsing failed\n");
255  goto failed;
256  }
257  break;
258  case CP_NIC_RX_LEN:
259  if (parse_int64(optarg, &c->nic_rx_len) != 0) {
260  fprintf(stderr, "nic rx len parsing failed\n");
261  goto failed;
262  }
263  break;
264  case CP_NIC_TX_LEN:
265  if (parse_int64(optarg, &c->nic_tx_len) != 0) {
266  fprintf(stderr, "nic tx len parsing failed\n");
267  goto failed;
268  }
269  break;
270  case CP_APP_KIN_LEN:
271  if (parse_int64(optarg, &c->app_kin_len) != 0) {
272  fprintf(stderr, "app kin len parsing failed\n");
273  goto failed;
274  }
275  break;
276  case CP_APP_KOUT_LEN:
277  if (parse_int64(optarg, &c->app_kout_len) != 0) {
278  fprintf(stderr, "app kout len parsing failed\n");
279  goto failed;
280  }
281  break;
282  case CP_ARP_TO:
283  if (parse_int32(optarg, &c->arp_to) != 0) {
284  fprintf(stderr, "arp timeout parsing failed\n");
285  goto failed;
286  }
287  break;
288  case CP_ARP_TO_MAX:
289  if (parse_int32(optarg, &c->arp_to_max) != 0) {
290  fprintf(stderr, "arp max timeout parsing failed\n");
291  goto failed;
292  }
293  break;
294  case CP_TCP_RTT_INIT:
295  if (parse_int32(optarg, &c->tcp_rtt_init) != 0) {
296  fprintf(stderr, "tcp rtt init parsing failed\n");
297  goto failed;
298  }
299  break;
300  case CP_TCP_LINK_BW:
301  if (parse_int32(optarg, &c->tcp_link_bw) != 0) {
302  fprintf(stderr, "tcp link bw timeout parsing failed\n");
303  goto failed;
304  }
305  break;
306  case CP_TCP_RXBUF_LEN:
307  if (parse_int64(optarg, &c->tcp_rxbuf_len) != 0) {
308  fprintf(stderr, "tcp rxbuf len parsing failed\n");
309  goto failed;
310  }
311  break;
312  case CP_TCP_TXBUF_LEN:
313  if (parse_int64(optarg, &c->tcp_txbuf_len) != 0) {
314  fprintf(stderr, "tcp txbuf len parsing failed\n");
315  goto failed;
316  }
317  break;
318  case CP_TCP_HANDSHAKE_TO:
319  if (parse_int32(optarg, &c->tcp_handshake_to) != 0) {
320  fprintf(stderr, "tcp handshake timeout parsing failed\n");
321  goto failed;
322  }
323  break;
324  case CP_TCP_HANDSHAKE_RETRIES:
325  if (parse_int32(optarg, &c->tcp_handshake_retries) != 0) {
326  fprintf(stderr, "tcp handshake retries parsing failed\n");
327  goto failed;
328  }
329  break;
330  case CP_CC:
331  if (!strcmp(optarg, "dctcp-win")) {
332  c->cc_algorithm = CONFIG_CC_DCTCP_WIN;
333  } else if (!strcmp(optarg, "dctcp-rate")) {
334  c->cc_algorithm = CONFIG_CC_DCTCP_RATE;
335  } else if (!strcmp(optarg, "const-rate")) {
336  c->cc_algorithm = CONFIG_CC_CONST_RATE;
337  } else if (!strcmp(optarg, "timely")) {
338  c->cc_algorithm = CONFIG_CC_TIMELY;
339  } else {
340  fprintf(stderr, "cc algorithm parsing failed\n");
341  goto failed;
342  }
343  break;
344  case CP_CC_CONTROL_GRANULARITY:
345  if (parse_int32(optarg, &c->cc_control_granularity) != 0) {
346  fprintf(stderr, "cc control granularity parsing failed\n");
347  goto failed;
348  }
349  break;
350  case CP_CC_CONTROL_INTERVAL:
351  if (parse_int32(optarg, &c->cc_control_interval) != 0) {
352  fprintf(stderr, "cc control granularity parsing failed\n");
353  goto failed;
354  }
355  break;
356  case CP_CC_REXMIT_INTS:
357  if (parse_int32(optarg, &c->cc_rexmit_ints) != 0) {
358  fprintf(stderr, "cc rexmit intervals parsing failed\n");
359  goto failed;
360  }
361  break;
362  case CP_CC_DCTCP_WEIGHT:
363  if (parse_double(optarg, &d) != 0 || d < 0 || d > 1) {
364  fprintf(stderr, "cc dctcp weight parsing failed\n");
365  goto failed;
366  }
367  c->cc_dctcp_weight = UINT32_MAX * d;
368  break;
369  case CP_CC_DCTCP_INIT:
370  if (parse_int32(optarg, &c->cc_dctcp_init) != 0) {
371  fprintf(stderr, "cc dctcp init parsing failed\n");
372  goto failed;
373  }
374  break;
375  case CP_CC_DCTCP_STEP:
376  if (parse_int32(optarg, &c->cc_dctcp_step) != 0) {
377  fprintf(stderr, "cc dctcp step parsing failed\n");
378  goto failed;
379  }
380  break;
381  case CP_CC_DCTCP_MIMD:
382  if (parse_double(optarg, &d) != 0 || d < 1 || d > 2) {
383  fprintf(stderr, "cc dctcp mimd parsing failed\n");
384  goto failed;
385  }
386  c->cc_dctcp_mimd = UINT32_MAX * (d - 1);
387  break;
388  case CP_CC_DCTCP_MIN:
389  if (parse_int32(optarg, &c->cc_dctcp_min) != 0) {
390  fprintf(stderr, "cc dctcp min parsing failed\n");
391  goto failed;
392  }
393  break;
394  case CP_CC_DCTCP_MINPKTS:
395  if (parse_int32(optarg, &c->cc_dctcp_minpkts) != 0) {
396  fprintf(stderr, "cc dctcp min packets parsing failed\n");
397  goto failed;
398  }
399  break;
400  case CP_CC_CONST_RATE:
401  if (parse_int32(optarg, &c->cc_const_rate) != 0) {
402  fprintf(stderr, "cc constant rate parsing failed\n");
403  goto failed;
404  }
405  break;
406  case CP_CC_TIMELY_TLOW:
407  if (parse_int32(optarg, &c->cc_timely_tlow) != 0) {
408  fprintf(stderr, "cc timely Tlow parsing failed\n");
409  goto failed;
410  }
411  break;
412  case CP_CC_TIMELY_THIGH:
413  if (parse_int32(optarg, &c->cc_timely_thigh) != 0) {
414  fprintf(stderr, "cc timely Thigh parsing failed\n");
415  goto failed;
416  }
417  break;
418  case CP_CC_TIMELY_STEP:
419  if (parse_int32(optarg, &c->cc_timely_step) != 0) {
420  fprintf(stderr, "cc timely step parsing failed\n");
421  goto failed;
422  }
423  break;
424  case CP_CC_TIMELY_INIT:
425  if (parse_int32(optarg, &c->cc_timely_init) != 0) {
426  fprintf(stderr, "cc timely init parsing failed\n");
427  goto failed;
428  }
429  break;
430  case CP_CC_TIMELY_ALPHA:
431  if (parse_double(optarg, &d) != 0 || d < 0 || d > 1) {
432  fprintf(stderr, "cc timely alpha parsing failed\n");
433  goto failed;
434  }
435  c->cc_timely_alpha = UINT32_MAX * d;
436  break;
437  case CP_CC_TIMELY_BETA:
438  if (parse_double(optarg, &d) != 0 || d < 0 || d > 1) {
439  fprintf(stderr, "cc timely beta parsing failed\n");
440  goto failed;
441  }
442  c->cc_timely_beta = UINT32_MAX * d;
443  break;
444  case CP_CC_TIMELY_MINRTT:
445  if (parse_int32(optarg, &c->cc_timely_min_rtt) != 0) {
446  fprintf(stderr, "cc timely min rtt parsing failed\n");
447  goto failed;
448  }
449  break;
450  case CP_CC_TIMELY_MINRATE:
451  if (parse_int32(optarg, &c->cc_timely_min_rate) != 0) {
452  fprintf(stderr, "cc timely min rate parsing failed\n");
453  goto failed;
454  }
455  break;
456  case CP_IP_ROUTE:
457  if (parse_route(optarg, c) != 0) {
458  goto failed;
459  }
460  break;
461  case CP_IP_ADDR:
462  c->ip_prefix = 0;
463  if (parse_cidr(optarg, &c->ip, &c->ip_prefix) != 0) {
464  fprintf(stderr, "Parsing IP failed\n");
465  goto failed;
466  }
467  break;
468  case CP_FP_CORES_MAX:
469  if (parse_int32(optarg, &c->fp_cores_max) != 0) {
470  fprintf(stderr, "fp cores max parsing failed\n");
471  goto failed;
472  }
473  break;
474  case CP_FP_NO_INTS:
475  c->fp_interrupts = 0;
476  c->fp_poll_interval_tas = UINT32_MAX;
477  break;
478  case CP_FP_NO_XSUMOFFLOAD:
479  c->fp_xsumoffload = 0;
480  break;
481  case CP_FP_NO_AUTOSCALE:
482  c->fp_autoscale = 0;
483  break;
484  case CP_FP_NO_HUGEPAGES:
485  c->fp_hugepages = 0;
486  break;
487  case CP_FP_VLAN_STRIP:
488  c->fp_vlan_strip = 1;
489  break;
490  case CP_FP_POLL_INTERVAL_TAS:
491  if (parse_int32(optarg, &c->fp_poll_interval_tas) != 0) {
492  fprintf(stderr, "fp tas poll interval parsing failed\n");
493  goto failed;
494  }
495  case CP_FP_POLL_INTERVAL_APP:
496  if (parse_int32(optarg, &c->fp_poll_interval_app) != 0) {
497  fprintf(stderr, "fp app poll interval parsing failed\n");
498  goto failed;
499  }
500  break;
501  break;
502 
503  case CP_KNI_NAME:
504  if (!(c->kni_name = strdup(optarg))) {
505  fprintf(stderr, "strdup kni name failed\n");
506  goto failed;
507  }
508  break;
509 
510  case CP_READY_FD:
511  if (parse_int32(optarg, &i) != 0) {
512  fprintf(stderr, "read fd parsing failed\n");
513  goto failed;
514  }
515  c->ready_fd = i;
516  break;
517  case CP_DPDK_EXTRA:
518  if (parse_arg_append(optarg, c) != 0) {
519  goto failed;
520  }
521  break;
522  case CP_QUIET:
523  c->quiet = 1;
524  break;
525 
526  case -1:
527  done = 1;
528  break;
529  case '?':
530  goto failed;
531  default:
532  abort();
533  }
534  }
535 
536  if (optind != argc) {
537  goto failed;
538  }
539 
540  if(c->ip == 0) {
541  fprintf(stderr, "ip-addr is a required argument!\n");
542  }
543 
544  return 0;
545 
546 failed:
547  config_defaults(c, argv[0]);
548  print_usage(c, argv[0]);
549  return -1;
550 }
551 
552 static int config_defaults(struct configuration *c, char *progname)
553 {
554  c->ip = 0;
555  c->shm_len = 1024 * 1024 * 1024;
556  c->nic_rx_len = 16 * 1024;
557  c->nic_tx_len = 16 * 1024;
558  c->app_kin_len = 1024 * 1024;
559  c->app_kout_len = 1024 * 1024;
560  c->arp_to = 500;
561  c->arp_to_max = 10000000;
562  c->tcp_rtt_init = 50;
563  c->tcp_link_bw = 10;
564  c->tcp_rxbuf_len = 8192;
565  c->tcp_txbuf_len = 8192;
566  c->tcp_handshake_to = 10000;
567  c->tcp_handshake_retries = 10;
568  c->cc_algorithm = CONFIG_CC_DCTCP_RATE;
569  c->cc_control_granularity = 50;
570  c->cc_control_interval = 2;
571  c->cc_rexmit_ints = 4;
572  c->cc_dctcp_weight = UINT32_MAX / 16;
573  c->cc_dctcp_init = 10000;
574  c->cc_dctcp_step = 10000;
575  c->cc_dctcp_mimd = 0;
576  c->cc_dctcp_min = 0;
577  c->cc_dctcp_minpkts = 50;
578  c->cc_const_rate = 0;
579  c->cc_timely_tlow = 30;
580  c->cc_timely_thigh = 150;
581  c->cc_timely_step = 10000;
582  c->cc_timely_init = 10000;
583  c->cc_timely_alpha = 0.02 * UINT32_MAX;
584  c->cc_timely_beta = 0.8 * UINT32_MAX;
585  c->cc_timely_min_rtt = 11;
586  c->cc_timely_min_rate = 10000;
587  c->fp_cores_max = 1;
588  c->fp_interrupts = 1;
589  c->fp_xsumoffload = 1;
590  c->fp_autoscale = 1;
591  c->fp_hugepages = 1;
592  c->fp_vlan_strip = 0;
593  c->fp_poll_interval_tas = 10000;
594  c->fp_poll_interval_app = 10000;
595  c->kni_name = NULL;
596  c->ready_fd = -1;
597  c->quiet = 0;
598 
599  c->dpdk_argc = 1;
600  if ((c->dpdk_argv = calloc(2, sizeof(*c->dpdk_argv))) == NULL) {
601  perror("config_defaults: calloc failed");
602  return -1;
603  }
604  c->dpdk_argv[0] = progname;
605 
606  return 0;
607 }
608 
609 static void print_usage(struct configuration *c, char *progname)
610 {
611  fprintf(stderr, "Usage: %s [OPTION]... --ip-addr=IP[/PREFIXLEN]\n"
612  "\n"
613  "Memory Sizes:\n"
614  " --shm-len=LEN Shared memory len "
615  "[default: %"PRIu64"]\n"
616  " --nic-rx-len=LEN Kernel rx queue len "
617  "[default: %"PRIu64"]\n"
618  " --nic-tx-len=LEN Kernel tx queue len "
619  "[default: %"PRIu64"]\n"
620  " --app-kin-len=LEN App->Kernel queue len "
621  "[default: %"PRIu64"]\n"
622  " --app-kout-len=LEN Kernel->App queue len "
623  "[default: %"PRIu64"]\n"
624  "\n"
625  "TCP protocol parameters:\n"
626  " --tcp-rtt-init=RTT Initial rtt for CC (us) "
627  "[default: %"PRIu32"]\n"
628  " --tcp-link-bw=BANDWIDTH Link bandwidth (gbps) "
629  "[default: %"PRIu32"]\n"
630  " --tcp-rxbuf-len Flow rx buffer len "
631  "[default: %"PRIu64"]\n"
632  " --tcp-txbuf-len Flow tx buffer len "
633  "[default: %"PRIu64"]\n"
634  " --tcp-handshake-timeout=TIMEOUT Handshake timeout (us) "
635  "[default: %"PRIu32"]\n"
636  " --tcp-handshake-retries=RETRIES Handshake retries "
637  "[default: %"PRIu32"]\n"
638  "\n"
639  "Congestion control parameters:\n"
640  " --cc=ALGORITHM Congestion-control algorithm "
641  "[default: dctcp-rate]\n"
642  " Options: dctcp-win, dctcp-rate, const-rate, timely\n"
643  " --cc-control-granularity=G Minimal control iteration "
644  "[default: %"PRIu32"]\n"
645  " --cc-control-interval=INT Control interval (multiples of RTT) "
646  "[default: %"PRIu32"]\n"
647  " --cc-rexmit-ints=INTERVALS #of RTTs without ACKs before rexmit "
648  "[default: %"PRIu32"]\n"
649  " --cc-dctcp-weight=WEIGHT DCTCP: EWMA weight for ECN rate "
650  "[default: %f]\n"
651  " --cc-dctcp-mimd=INC_FACT DCTCP: enable multiplicative inc "
652  "[default: disabled]\n"
653  " --cc-dctcp-min=RATE DCTCP: minimum cap for flow rates "
654  "[default: %"PRIu32"]\n"
655  " --cc-const-rate=RATE Constant rate for all flows "
656  "[default: %"PRIu32"]\n"
657  " --cc-timely-tlow=TIME Timely: low threshold (us) "
658  "[default: %"PRIu32"]\n"
659  " --cc-timely-thigh=TIME Timely: high threshold (us) "
660  "[default: %"PRIu32"]\n"
661  " --cc-timely-step=STEP Timely: additive increment step (kbps) "
662  "[default: %"PRIu32"]\n"
663  " --cc-timely-init=RATE Timely: initial flow rate (kbps) "
664  "[default: %"PRIu32"]\n"
665  " --cc-timely-alpha=FRAC Timely: EWMA weight for rtt diff "
666  "[default: %f]\n"
667  " --cc-timely-beta=FRAC Timely: mult. decr. factor "
668  "[default: %f]\n"
669  " --cc-timely-minrtt=RTT Timely: minimal rtt without queueing "
670  "[default: %"PRIu32"]\n"
671  " --cc-timely-minrate=RTT Timely: minimal rate to use "
672  "[default: %"PRIu32"]\n"
673  "\n"
674  "IP protocol parameters:\n"
675  " --ip-route=DEST[/PREFIX],NEXTHOP Add route\n"
676  " --ip-addr=ADDR[/PREFIXLEN] Set local IP address\n"
677  "\n"
678  "ARP protocol parameters:\n"
679  " --arp-timeout=TIMEOUT ARP request timeout (us) "
680  "[default: %"PRIu32"]\n"
681  " --arp-timeout-max=TIMEOUT ARP request max timeout (us) "
682  "[default: %"PRIu32"]\n"
683  "\n"
684  "Fast path:\n"
685  " --fp-cores-max=CORES Max cores used for fast path "
686  "[default: %"PRIu32"]\n"
687  " --fp-no-ints Disable Interrupts "
688  "[default: enabled]\n"
689  " --fp-no-xsumoffload Disable TX Checksum offload "
690  "[default: enabled]\n"
691  " --fp-no-autoscale Disable autoscaling "
692  "[default: enabled]\n"
693  " --fp-no-hugepages Disable hugepages for SHM "
694  "[default: enabled]\n"
695  " --fp-poll-interval-tas TAS polling interval before blocking "
696  "in us [default: %"PRIu32"]\n"
697  " --fp-poll-interval-app App polling interval before blocking "
698  "in us [default: %"PRIu32"]\n"
699  " --dpdk-extra=ARG Add extra DPDK argument\n"
700  "\n"
701  "Host kernel interface:\n"
702  " --kni-name=NAME Network interface name to expose "
703  "[default: disabled]\n"
704  "\n"
705  "Miscelaneous:\n"
706  " --quiet Disable non-essential logging "
707  "[default: disabled]\n"
708  " --ready-fd=FD File descriptor to signal readiness "
709  "[default: disabled]\n"
710  "\n",
711  progname, c->shm_len,
716  (double) c->cc_dctcp_weight / UINT32_MAX, c->cc_dctcp_min,
719  (double) c->cc_timely_alpha / UINT32_MAX,
720  (double) c->cc_timely_beta / UINT32_MAX, c->cc_timely_min_rtt,
723 }
724 
725 static inline int parse_int64(const char *s, uint64_t *pi)
726 {
727  char *end;
728  *pi = strtoul(s, &end, 10);
729  if (!*s || *end)
730  return -1;
731  return 0;
732 }
733 
734 static inline int parse_int32(const char *s, uint32_t *pi)
735 {
736  char *end;
737  *pi = strtoul(s, &end, 10);
738  if (!*s || *end)
739  return -1;
740  return 0;
741 }
742 
743 static inline int parse_int8(const char *s, uint8_t *pi)
744 {
745  char *end;
746  *pi = strtoul(s, &end, 10);
747  if (!*s || *end)
748  return -1;
749  return 0;
750 }
751 
752 static inline int parse_double(const char *s, double *pd)
753 {
754  char *end;
755  *pd = strtod(s, &end);
756  if (!*s || *end)
757  return -1;
758  return 0;
759 }
760 
761 static inline int parse_cidr(char *s, uint32_t *ip, uint8_t *prefix)
762 {
763  char *slash;
764 
765  /* parse /prefix and replace / by \0 (if applicable)*/
766  if ((slash = strrchr(s, '/')) != NULL) {
767  if (parse_int8(slash + 1, prefix) != 0) {
768  fprintf(stderr, "parse_cidr: parsing prefix (%s) failed\n", slash);
769  return -1;
770  }
771  *slash = 0;
772  }
773 
774  if (util_parse_ipv4(s, ip) != 0) {
775  fprintf(stderr, "parse_cidr: parsing IP (%s) failed\n", s);
776  return -1;
777  }
778 
779  return 0;
780 }
781 
782 static inline int parse_route(char *s, struct configuration *c)
783 {
784  struct config_route *r, *r_p;
785  char *comma;
786 
787  if ((r = calloc(1, sizeof(*r))) == NULL) {
788  fprintf(stderr, "parse_route: alloc failed\n");
789  return -1;
790  }
791 
792  /* split destination from next hop */
793  if ((comma = strchr(s, ',')) == NULL) {
794  fprintf(stderr, "parse_route: no comma found (%s)\n", s);
795  goto failed;
796  }
797  *comma = 0;
798 
799  /* parse destination */
800  r->ip_prefix = 32;
801  if (parse_cidr(s, &r->ip, &r->ip_prefix) != 0) {
802  fprintf(stderr, "parse_route: parsing destination (%s) failed\n", s);
803  goto failed;
804  }
805 
806  /* parse next hop */
807  if (util_parse_ipv4(comma + 1, &r->next_hop_ip) != 0) {
808  fprintf(stderr, "parse_route: parsing next hop (%s) failed\n", comma + 1);
809  goto failed;
810  }
811 
812  /* add to route list */
813  r->next = NULL;
814  if (c->routes == NULL) {
815  c->routes = r;
816  } else {
817  for (r_p = c->routes; r_p->next != NULL; r_p = r_p->next);
818  r_p->next = r;
819  }
820  return 0;
821 
822 failed:
823  return -1;
824 }
825 
826 static inline int parse_arg_append(char *s, struct configuration *c)
827 {
828  char **new;
829 
830  if ((new = realloc(c->dpdk_argv, sizeof(char *) * (c->dpdk_argc + 2)))
831  == NULL)
832  {
833  perror("parse_arg_append: alloc failed");
834  return -1;
835  }
836 
837  new[c->dpdk_argc++] = strdup(s);
838  c->dpdk_argv = new;
839 
840  return 0;
841 }
uint32_t fp_autoscale
Definition: config.h:121
uint32_t cc_timely_alpha
Definition: config.h:107
uint32_t cc_timely_thigh
Definition: config.h:101
uint32_t cc_timely_tlow
Definition: config.h:99
uint32_t fp_hugepages
Definition: config.h:123
int dpdk_argc
Definition: config.h:139
uint32_t fp_cores_max
Definition: config.h:115
uint32_t cc_dctcp_weight
Definition: config.h:85
char ** dpdk_argv
Definition: config.h:137
uint32_t tcp_handshake_to
Definition: config.h:63
uint32_t cc_timely_beta
Definition: config.h:109
uint32_t cc_dctcp_min
Definition: config.h:93
uint32_t tcp_rtt_init
Definition: config.h:59
uint8_t ip_prefix
Definition: config.h:147
uint32_t fp_interrupts
Definition: config.h:117
uint8_t ip_prefix
Definition: config.h:69
uint32_t cc_control_granularity
Definition: config.h:79
struct config_route * routes
Definition: config.h:71
uint32_t cc_control_interval
Definition: config.h:81
uint32_t cc_dctcp_mimd
Definition: config.h:91
uint32_t cc_dctcp_step
Definition: config.h:89
uint32_t cc_timely_min_rate
Definition: config.h:113
uint32_t cc_dctcp_minpkts
Definition: config.h:95
uint32_t cc_dctcp_init
Definition: config.h:87
uint64_t nic_tx_len
Definition: config.h:49
uint32_t ip
Definition: config.h:145
uint32_t cc_timely_step
Definition: config.h:103
char * kni_name
Definition: config.h:131
uint32_t fp_xsumoffload
Definition: config.h:119
uint32_t fp_vlan_strip
Definition: config.h:125
uint32_t cc_rexmit_ints
Definition: config.h:83
uint32_t fp_poll_interval_app
Definition: config.h:129
int ready_fd
Definition: config.h:133
uint64_t nic_rx_len
Definition: config.h:47
uint64_t app_kout_len
Definition: config.h:53
uint32_t arp_to
Definition: config.h:73
uint32_t cc_timely_min_rtt
Definition: config.h:111
struct config_route * next
Definition: config.h:151
uint64_t app_kin_len
Definition: config.h:51
uint32_t next_hop_ip
Definition: config.h:149
uint32_t ip
Definition: config.h:67
uint64_t tcp_txbuf_len
Definition: config.h:57
uint32_t tcp_handshake_retries
Definition: config.h:65
uint32_t arp_to_max
Definition: config.h:75
uint32_t cc_const_rate
Definition: config.h:97
enum config_cc_algorithm cc_algorithm
Definition: config.h:77
uint32_t cc_timely_init
Definition: config.h:105
uint64_t tcp_rxbuf_len
Definition: config.h:55
uint32_t tcp_link_bw
Definition: config.h:61
uint32_t fp_poll_interval_tas
Definition: config.h:127