50 CP_TCP_HANDSHAKE_RETRIES,
52 CP_CC_CONTROL_GRANULARITY,
53 CP_CC_CONTROL_INTERVAL,
78 CP_FP_POLL_INTERVAL_TAS,
79 CP_FP_POLL_INTERVAL_APP,
86 static struct option opts[] = {
88 .has_arg = required_argument,
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,
105 { .name =
"arp-timeout-max",
106 .has_arg = required_argument,
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 },
127 .has_arg = required_argument,
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 },
187 .has_arg = required_argument,
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 },
223 .has_arg = no_argument,
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);
238 int config_parse(
struct configuration *c,
int argc,
char *argv[])
244 if (config_defaults(c, argv[0]) != 0) {
245 fprintf(stderr,
"config_parse: config defaults failed\n");
250 ret = getopt_long(argc, argv,
"", opts, NULL);
253 if (parse_int64(optarg, &c->shm_len) != 0) {
254 fprintf(stderr,
"shm len parsing failed\n");
259 if (parse_int64(optarg, &c->
nic_rx_len) != 0) {
260 fprintf(stderr,
"nic rx len parsing failed\n");
265 if (parse_int64(optarg, &c->
nic_tx_len) != 0) {
266 fprintf(stderr,
"nic tx len parsing failed\n");
272 fprintf(stderr,
"app kin len parsing failed\n");
276 case CP_APP_KOUT_LEN:
278 fprintf(stderr,
"app kout len parsing failed\n");
283 if (parse_int32(optarg, &c->
arp_to) != 0) {
284 fprintf(stderr,
"arp timeout parsing failed\n");
289 if (parse_int32(optarg, &c->
arp_to_max) != 0) {
290 fprintf(stderr,
"arp max timeout parsing failed\n");
294 case CP_TCP_RTT_INIT:
296 fprintf(stderr,
"tcp rtt init parsing failed\n");
302 fprintf(stderr,
"tcp link bw timeout parsing failed\n");
306 case CP_TCP_RXBUF_LEN:
308 fprintf(stderr,
"tcp rxbuf len parsing failed\n");
312 case CP_TCP_TXBUF_LEN:
314 fprintf(stderr,
"tcp txbuf len parsing failed\n");
318 case CP_TCP_HANDSHAKE_TO:
320 fprintf(stderr,
"tcp handshake timeout parsing failed\n");
324 case CP_TCP_HANDSHAKE_RETRIES:
326 fprintf(stderr,
"tcp handshake retries parsing failed\n");
331 if (!strcmp(optarg,
"dctcp-win")) {
333 }
else if (!strcmp(optarg,
"dctcp-rate")) {
335 }
else if (!strcmp(optarg,
"const-rate")) {
337 }
else if (!strcmp(optarg,
"timely")) {
340 fprintf(stderr,
"cc algorithm parsing failed\n");
344 case CP_CC_CONTROL_GRANULARITY:
346 fprintf(stderr,
"cc control granularity parsing failed\n");
350 case CP_CC_CONTROL_INTERVAL:
352 fprintf(stderr,
"cc control granularity parsing failed\n");
356 case CP_CC_REXMIT_INTS:
358 fprintf(stderr,
"cc rexmit intervals parsing failed\n");
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");
369 case CP_CC_DCTCP_INIT:
371 fprintf(stderr,
"cc dctcp init parsing failed\n");
375 case CP_CC_DCTCP_STEP:
377 fprintf(stderr,
"cc dctcp step parsing failed\n");
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");
388 case CP_CC_DCTCP_MIN:
390 fprintf(stderr,
"cc dctcp min parsing failed\n");
394 case CP_CC_DCTCP_MINPKTS:
396 fprintf(stderr,
"cc dctcp min packets parsing failed\n");
400 case CP_CC_CONST_RATE:
402 fprintf(stderr,
"cc constant rate parsing failed\n");
406 case CP_CC_TIMELY_TLOW:
408 fprintf(stderr,
"cc timely Tlow parsing failed\n");
412 case CP_CC_TIMELY_THIGH:
414 fprintf(stderr,
"cc timely Thigh parsing failed\n");
418 case CP_CC_TIMELY_STEP:
420 fprintf(stderr,
"cc timely step parsing failed\n");
424 case CP_CC_TIMELY_INIT:
426 fprintf(stderr,
"cc timely init parsing failed\n");
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");
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");
444 case CP_CC_TIMELY_MINRTT:
446 fprintf(stderr,
"cc timely min rtt parsing failed\n");
450 case CP_CC_TIMELY_MINRATE:
452 fprintf(stderr,
"cc timely min rate parsing failed\n");
457 if (parse_route(optarg, c) != 0) {
463 if (parse_cidr(optarg, &c->
ip, &c->
ip_prefix) != 0) {
464 fprintf(stderr,
"Parsing IP failed\n");
468 case CP_FP_CORES_MAX:
470 fprintf(stderr,
"fp cores max parsing failed\n");
478 case CP_FP_NO_XSUMOFFLOAD:
481 case CP_FP_NO_AUTOSCALE:
484 case CP_FP_NO_HUGEPAGES:
487 case CP_FP_VLAN_STRIP:
490 case CP_FP_POLL_INTERVAL_TAS:
492 fprintf(stderr,
"fp tas poll interval parsing failed\n");
495 case CP_FP_POLL_INTERVAL_APP:
497 fprintf(stderr,
"fp app poll interval parsing failed\n");
504 if (!(c->
kni_name = strdup(optarg))) {
505 fprintf(stderr,
"strdup kni name failed\n");
511 if (parse_int32(optarg, &i) != 0) {
512 fprintf(stderr,
"read fd parsing failed\n");
518 if (parse_arg_append(optarg, c) != 0) {
536 if (optind != argc) {
541 fprintf(stderr,
"ip-addr is a required argument!\n");
547 config_defaults(c, argv[0]);
548 print_usage(c, argv[0]);
552 static int config_defaults(
struct configuration *c,
char *progname)
555 c->shm_len = 1024 * 1024 * 1024;
601 perror(
"config_defaults: calloc failed");
609 static void print_usage(
struct configuration *c,
char *progname)
611 fprintf(stderr,
"Usage: %s [OPTION]... --ip-addr=IP[/PREFIXLEN]\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" 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" 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 " 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 " 667 " --cc-timely-beta=FRAC Timely: mult. decr. factor " 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" 674 "IP protocol parameters:\n" 675 " --ip-route=DEST[/PREFIX],NEXTHOP Add route\n" 676 " --ip-addr=ADDR[/PREFIXLEN] Set local IP address\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" 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" 701 "Host kernel interface:\n" 702 " --kni-name=NAME Network interface name to expose " 703 "[default: disabled]\n" 706 " --quiet Disable non-essential logging " 707 "[default: disabled]\n" 708 " --ready-fd=FD File descriptor to signal readiness " 709 "[default: disabled]\n" 711 progname, c->shm_len,
725 static inline int parse_int64(
const char *s, uint64_t *pi)
728 *pi = strtoul(s, &end, 10);
734 static inline int parse_int32(
const char *s, uint32_t *pi)
737 *pi = strtoul(s, &end, 10);
743 static inline int parse_int8(
const char *s, uint8_t *pi)
746 *pi = strtoul(s, &end, 10);
752 static inline int parse_double(
const char *s,
double *pd)
755 *pd = strtod(s, &end);
761 static inline int parse_cidr(
char *s, uint32_t *ip, uint8_t *prefix)
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);
774 if (util_parse_ipv4(s, ip) != 0) {
775 fprintf(stderr,
"parse_cidr: parsing IP (%s) failed\n", s);
782 static inline int parse_route(
char *s,
struct configuration *c)
787 if ((r = calloc(1,
sizeof(*r))) == NULL) {
788 fprintf(stderr,
"parse_route: alloc failed\n");
793 if ((comma = strchr(s,
',')) == NULL) {
794 fprintf(stderr,
"parse_route: no comma found (%s)\n", s);
802 fprintf(stderr,
"parse_route: parsing destination (%s) failed\n", s);
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);
826 static inline int parse_arg_append(
char *s,
struct configuration *c)
833 perror(
"parse_arg_append: alloc failed");
uint32_t tcp_handshake_to
uint32_t cc_control_granularity
struct config_route * routes
uint32_t cc_control_interval
uint32_t cc_timely_min_rate
uint32_t cc_dctcp_minpkts
uint32_t fp_poll_interval_app
uint32_t cc_timely_min_rtt
struct config_route * next
uint32_t tcp_handshake_retries
enum config_cc_algorithm cc_algorithm
uint32_t fp_poll_interval_tas