diff options
-rw-r--r-- | accel-pppd/accel-ppp.conf | 1 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 6 | ||||
-rw-r--r-- | accel-pppd/shaper/leaf_qdisc.c | 133 | ||||
-rw-r--r-- | accel-pppd/shaper/shaper.c | 3 | ||||
-rw-r--r-- | accel-pppd/shaper/shaper.h | 4 |
5 files changed, 146 insertions, 1 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index e4e7b0b..af8967f 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -212,6 +212,7 @@ gw-ip-address=192.168.100.1 up-limiter=police down-limiter=tbf #leaf-qdisc=sfq perturb 10 +#leaf-qdisc=fq_codel [limit PACKETS] [flows NUMBER] [target TIME] [interval TIME] [quantum BYTES] [[no]ecn] #rate-multiplier=1 verbose=1 diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 965116f..ced42ac 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -856,7 +856,11 @@ Specifies downstream rate limiting method. .TP .BI "leaf-qdisc=" "qdisc parameters" In case if htb is used as up-limiter or down-limiter specified leaf qdisc can be attached automaticaly. -At present only sfq qdisc is implemented. Parameters are same as for tc: [ limit NUMBER ] [ perturn SECS ] [ quantum BYTES ]. +At present sfq and fq_codel qdiscs are implemented. Parameters are same as for tc: +.br +sfq [ limit NUMBER ] [ perturn SECS ] [ quantum BYTES ] +.br +fq_codel [ limit PACKETS ] [flows NUMBER ] [ target TIME ] [ interval TIME ] [quantum BYTES ] [ [no]ecn ] .TP .BI "rate-multiplier=" n Due to accel-ppp operates with rates in kilobit basis if you send rates in different basis then you can use this option to bring your values to kilobits. diff --git a/accel-pppd/shaper/leaf_qdisc.c b/accel-pppd/shaper/leaf_qdisc.c index 51b8c8d..4240a34 100644 --- a/accel-pppd/shaper/leaf_qdisc.c +++ b/accel-pppd/shaper/leaf_qdisc.c @@ -56,6 +56,34 @@ static int parse_size(const char *str, int *r) return 0; } +static int parse_time(const char *str, int *r) +{ + double t; + char *endptr; + + t = strtod(str, &endptr); + + if (endptr == str) + return -1; + + if (*endptr == 0) { + *r = t; + return 0; + } + + if (strcmp(endptr, "s") == 0 || strcmp(endptr, "sec") == 0) + *r = t * TIME_UNITS_PER_SEC; + else if (strcmp(endptr, "ms") == 0 || strcmp(endptr, "msec") == 0) + *r = t * TIME_UNITS_PER_SEC/1000; + else if (strcmp(endptr, "us") == 0 || strcmp(endptr, "usec") == 0) + *r = t * TIME_UNITS_PER_SEC/1000000; + else + return -1; + + return 0; +} + + static int parse_int(const char *str, int *r) { char *endptr; @@ -125,6 +153,70 @@ out: return 0; } +static int parse_fq_codel(char *str) +{ + char *ptr1, *ptr2; + + conf_lq_arg6 = -1; + + if (!*str) + goto out; + + while (1) { + for (ptr1 = str + 1; *ptr1 && *ptr1 != ' '; ptr1++); + + if (!*ptr1) + return -1; + + *ptr1 = 0; + + for (ptr1++; *ptr1 && *ptr1 == ' '; ptr1++); + + if (!*ptr1) + return -1; + + for (ptr2 = ptr1 + 1; *ptr2 && *ptr2 != ' '; ptr2++); + + if (*ptr2) { + *ptr2 = 0; + for (ptr2++; *ptr2 && *ptr2 == ' '; ptr2++); + } + + if (strcmp(str, "limit") == 0) { + if (parse_u32(ptr1, &conf_lq_arg1)) + return -1; + } else if (strcmp(str, "flows") == 0) { + if (parse_u32(ptr1, &conf_lq_arg2)) + return -1; + } else if (strcmp(str, "quantum") == 0) { + if (parse_u32(ptr1, &conf_lq_arg3)) + return -1; + } else if (strcmp(str, "target") == 0) { + if (parse_time(ptr1, &conf_lq_arg4)) + return -1; + } else if (strcmp(str, "interval") == 0) { + if (parse_time(ptr1, &conf_lq_arg5)) + return -1; + } else if (strcmp(str, "ecn") == 0) { + conf_lq_arg6 = 1; + } else if (strcmp(str, "noecn") == 0) { + conf_lq_arg6 = 0; + } else + return -1; + + if (*ptr2 == 0) + break; + + str = ptr2; + } + +out: + conf_leaf_qdisc = LEAF_QDISC_FQ_CODEL; + + return 0; +} + + void leaf_qdisc_parse(const char *opt) { char *ptr1; @@ -140,6 +232,9 @@ void leaf_qdisc_parse(const char *opt) if (strcmp(str, "sfq") == 0) { if (parse_sfq(ptr1)) goto out_err; + } if (strcmp(str, "fq_codel") == 0) { + if (parse_fq_codel(ptr1)) + goto out_err; } else log_emerg("shaper: unknown leaf-qdisc '%s'\n", str); @@ -175,12 +270,50 @@ static int install_sfq(struct rtnl_handle *rth, int ifindex, int parent, int han return tc_qdisc_modify(rth, ifindex, RTM_NEWQDISC, NLM_F_EXCL|NLM_F_CREATE, &opt); } +static int qdisc_fq_codel(struct qdisc_opt *qopt, struct nlmsghdr *n) +{ + struct rtattr *tail = NLMSG_TAIL(n); + + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + + if (conf_lq_arg1) + addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &conf_lq_arg1, sizeof(conf_lq_arg1)); + if (conf_lq_arg2) + addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &conf_lq_arg2, sizeof(conf_lq_arg2)); + if (conf_lq_arg3) + addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &conf_lq_arg3, sizeof(conf_lq_arg3)); + if (conf_lq_arg4) + addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &conf_lq_arg4, sizeof(conf_lq_arg4)); + if (conf_lq_arg5) + addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &conf_lq_arg5, sizeof(conf_lq_arg5)); + if (conf_lq_arg6 != -1) + addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &conf_lq_arg6, sizeof(conf_lq_arg6)); + + tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail; + + return 0; +} + +static int install_fq_codel(struct rtnl_handle *rth, int ifindex, int parent, int handle) +{ + struct qdisc_opt opt = { + .kind = "fq_codel", + .handle = handle, + .parent = parent, + .qdisc = qdisc_fq_codel, + }; + + return tc_qdisc_modify(rth, ifindex, RTM_NEWQDISC, NLM_F_EXCL|NLM_F_CREATE, &opt); +} int install_leaf_qdisc(struct rtnl_handle *rth, int ifindex, int parent, int handle) { if (conf_leaf_qdisc == LEAF_QDISC_SFQ) return install_sfq(rth, ifindex, parent, handle); + if (conf_leaf_qdisc == LEAF_QDISC_FQ_CODEL) + return install_fq_codel(rth, ifindex, parent, handle); + return 0; } diff --git a/accel-pppd/shaper/shaper.c b/accel-pppd/shaper/shaper.c index c27ec72..40677de 100644 --- a/accel-pppd/shaper/shaper.c +++ b/accel-pppd/shaper/shaper.c @@ -50,6 +50,9 @@ int conf_leaf_qdisc; int conf_lq_arg1; int conf_lq_arg2; int conf_lq_arg3; +int conf_lq_arg4; +int conf_lq_arg5; +int conf_lq_arg6; static int temp_down_speed; static int temp_up_speed; diff --git a/accel-pppd/shaper/shaper.h b/accel-pppd/shaper/shaper.h index 4e6b9ff..946c991 100644 --- a/accel-pppd/shaper/shaper.h +++ b/accel-pppd/shaper/shaper.h @@ -6,6 +6,7 @@ #define LIM_HTB 2 #define LEAF_QDISC_SFQ 1 +#define LEAF_QDISC_FQ_CODEL 2 struct rtnl_handle; struct nlmsghdr; @@ -39,6 +40,9 @@ extern int conf_leaf_qdisc; extern int conf_lq_arg1; extern int conf_lq_arg2; extern int conf_lq_arg3; +extern int conf_lq_arg4; +extern int conf_lq_arg5; +extern int conf_lq_arg6; int install_limiter(struct ap_session *ses, int down_speed, int down_burst, int up_speed, int up_burst); int remove_limiter(struct ap_session *ses); |