tc: q_red: Support 'nodrop' flag
Recognize the new configuration option of the RED Qdisc, "nodrop". Add support for passing flags through TCA_RED_FLAGS, and use it when passing TC_RED_NODROP flag. Signed-off-by: Petr Machata <petrm@mellanox.com> Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
parent
1c74c20cbe
commit
6c10fdca70
|
|
@ -13,7 +13,7 @@ bytes
|
||||||
bytes
|
bytes
|
||||||
.B [ burst
|
.B [ burst
|
||||||
packets
|
packets
|
||||||
.B ] [ ecn ] [ harddrop] [ bandwidth
|
.B ] [ ecn ] [ harddrop ] [ nodrop ] [ bandwidth
|
||||||
rate
|
rate
|
||||||
.B ] [ probability
|
.B ] [ probability
|
||||||
chance
|
chance
|
||||||
|
|
@ -123,6 +123,10 @@ If average flow queue size is above
|
||||||
.B max
|
.B max
|
||||||
bytes, this parameter forces a drop instead of ecn marking.
|
bytes, this parameter forces a drop instead of ecn marking.
|
||||||
.TP
|
.TP
|
||||||
|
nodrop
|
||||||
|
With this parameter, traffic that should be marked, but is not ECN-capable, is
|
||||||
|
enqueued. Without the parameter it is early-dropped.
|
||||||
|
.TP
|
||||||
adaptive
|
adaptive
|
||||||
(Added in linux-3.3) Sets RED in adaptive mode as described in http://icir.org/floyd/papers/adaptiveRed.pdf
|
(Added in linux-3.3) Sets RED in adaptive mode as described in http://icir.org/floyd/papers/adaptiveRed.pdf
|
||||||
.nf
|
.nf
|
||||||
|
|
|
||||||
25
tc/q_red.c
25
tc/q_red.c
|
|
@ -30,12 +30,17 @@ static void explain(void)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: ... red limit BYTES [min BYTES] [max BYTES] avpkt BYTES [burst PACKETS]\n"
|
"Usage: ... red limit BYTES [min BYTES] [max BYTES] avpkt BYTES [burst PACKETS]\n"
|
||||||
" [adaptive] [probability PROBABILITY] [bandwidth KBPS]\n"
|
" [adaptive] [probability PROBABILITY] [bandwidth KBPS]\n"
|
||||||
" [ecn] [harddrop]\n");
|
" [ecn] [harddrop] [nodrop]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RED_SUPPORTED_FLAGS (TC_RED_HISTORIC_FLAGS | TC_RED_NODROP)
|
||||||
|
|
||||||
static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
||||||
struct nlmsghdr *n, const char *dev)
|
struct nlmsghdr *n, const char *dev)
|
||||||
{
|
{
|
||||||
|
struct nla_bitfield32 flags_bf = {
|
||||||
|
.selector = RED_SUPPORTED_FLAGS,
|
||||||
|
};
|
||||||
struct tc_red_qopt opt = {};
|
struct tc_red_qopt opt = {};
|
||||||
unsigned int burst = 0;
|
unsigned int burst = 0;
|
||||||
unsigned int avpkt = 0;
|
unsigned int avpkt = 0;
|
||||||
|
|
@ -95,13 +100,15 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (strcmp(*argv, "ecn") == 0) {
|
} else if (strcmp(*argv, "ecn") == 0) {
|
||||||
opt.flags |= TC_RED_ECN;
|
flags_bf.value |= TC_RED_ECN;
|
||||||
} else if (strcmp(*argv, "harddrop") == 0) {
|
} else if (strcmp(*argv, "harddrop") == 0) {
|
||||||
opt.flags |= TC_RED_HARDDROP;
|
flags_bf.value |= TC_RED_HARDDROP;
|
||||||
|
} else if (strcmp(*argv, "nodrop") == 0) {
|
||||||
|
flags_bf.value |= TC_RED_NODROP;
|
||||||
} else if (strcmp(*argv, "adaptative") == 0) {
|
} else if (strcmp(*argv, "adaptative") == 0) {
|
||||||
opt.flags |= TC_RED_ADAPTATIVE;
|
flags_bf.value |= TC_RED_ADAPTATIVE;
|
||||||
} else if (strcmp(*argv, "adaptive") == 0) {
|
} else if (strcmp(*argv, "adaptive") == 0) {
|
||||||
opt.flags |= TC_RED_ADAPTATIVE;
|
flags_bf.value |= TC_RED_ADAPTATIVE;
|
||||||
} else if (strcmp(*argv, "help") == 0) {
|
} else if (strcmp(*argv, "help") == 0) {
|
||||||
explain();
|
explain();
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -154,6 +161,7 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
||||||
addattr_l(n, 1024, TCA_RED_STAB, sbuf, 256);
|
addattr_l(n, 1024, TCA_RED_STAB, sbuf, 256);
|
||||||
max_P = probability * pow(2, 32);
|
max_P = probability * pow(2, 32);
|
||||||
addattr_l(n, 1024, TCA_RED_MAX_P, &max_P, sizeof(max_P));
|
addattr_l(n, 1024, TCA_RED_MAX_P, &max_P, sizeof(max_P));
|
||||||
|
addattr_l(n, 1024, TCA_RED_FLAGS, &flags_bf, sizeof(flags_bf));
|
||||||
addattr_nest_end(n, tail);
|
addattr_nest_end(n, tail);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -161,6 +169,7 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
||||||
static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
|
static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
|
||||||
{
|
{
|
||||||
struct rtattr *tb[TCA_RED_MAX + 1];
|
struct rtattr *tb[TCA_RED_MAX + 1];
|
||||||
|
struct nla_bitfield32 *flags_bf;
|
||||||
struct tc_red_qopt *qopt;
|
struct tc_red_qopt *qopt;
|
||||||
__u32 max_P = 0;
|
__u32 max_P = 0;
|
||||||
|
|
||||||
|
|
@ -183,6 +192,12 @@ static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
|
||||||
RTA_PAYLOAD(tb[TCA_RED_MAX_P]) >= sizeof(__u32))
|
RTA_PAYLOAD(tb[TCA_RED_MAX_P]) >= sizeof(__u32))
|
||||||
max_P = rta_getattr_u32(tb[TCA_RED_MAX_P]);
|
max_P = rta_getattr_u32(tb[TCA_RED_MAX_P]);
|
||||||
|
|
||||||
|
if (tb[TCA_RED_FLAGS] &&
|
||||||
|
RTA_PAYLOAD(tb[TCA_RED_FLAGS]) >= sizeof(*flags_bf)) {
|
||||||
|
flags_bf = RTA_DATA(tb[TCA_RED_FLAGS]);
|
||||||
|
qopt->flags = flags_bf->value;
|
||||||
|
}
|
||||||
|
|
||||||
print_uint(PRINT_JSON, "limit", NULL, qopt->limit);
|
print_uint(PRINT_JSON, "limit", NULL, qopt->limit);
|
||||||
print_string(PRINT_FP, NULL, "limit %s ", sprint_size(qopt->limit, b1));
|
print_string(PRINT_FP, NULL, "limit %s ", sprint_size(qopt->limit, b1));
|
||||||
print_uint(PRINT_JSON, "min", NULL, qopt->qth_min);
|
print_uint(PRINT_JSON, "min", NULL, qopt->qth_min);
|
||||||
|
|
|
||||||
|
|
@ -116,4 +116,9 @@ void tc_red_print_flags(__u32 flags)
|
||||||
print_bool(PRINT_ANY, "adaptive", "adaptive ", true);
|
print_bool(PRINT_ANY, "adaptive", "adaptive ", true);
|
||||||
else
|
else
|
||||||
print_bool(PRINT_ANY, "adaptive", NULL, false);
|
print_bool(PRINT_ANY, "adaptive", NULL, false);
|
||||||
|
|
||||||
|
if (flags & TC_RED_NODROP)
|
||||||
|
print_bool(PRINT_ANY, "nodrop", "nodrop ", true);
|
||||||
|
else
|
||||||
|
print_bool(PRINT_ANY, "nodrop", NULL, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue