1c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger/*
2c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger * q_qfq.c	QFQ.
3c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *
4c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *		This program is free software; you can redistribute it and/or
5c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *		modify it under the terms of the GNU General Public License
6c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *		as published by the Free Software Foundation; either version
7c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *		2 of the License, or (at your option) any later version.
8c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *
9c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger * Authors:	Stephen Hemminger <shemminger@vyatta.com>
10c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *		Fabio Checconi <fabio@gandalf.sssup.it>
11c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger *
12c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger */
13c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include <syslog.h>
14c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include <fcntl.h>
15c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include <sys/socket.h>
16c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include <netinet/in.h>
17c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include <arpa/inet.h>
18c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include <string.h>
19c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
20c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include "utils.h"
21c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger#include "tc_util.h"
22c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
23c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstatic void explain(void)
24c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger{
25c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	fprintf(stderr, "Usage: ... qfq\n");
26c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger}
27c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
28c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstatic void explain1(const char *arg)
29c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger{
30c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	fprintf(stderr, "Illegal \"%s\"\n", arg);
31c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger}
32c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
33c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstatic void explain_class(void)
34c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger{
35c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	fprintf(stderr, "Usage: ... qfq weight NUMBER maxpkt BYTES\n");
36c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger}
37c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
38c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstatic int qfq_parse_opt(struct qdisc_util *qu, int argc, char **argv,
39c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			 struct nlmsghdr *n)
40c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger{
41c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	while (argc > 0) {
42c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		if (matches(*argv, "help") == 0) {
43c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			explain();
44c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			return -1;
45c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		} else {
46c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			fprintf(stderr, "What is \"%s\"?\n", *argv);
47c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			explain();
48c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			return -1;
49c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		}
50c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		argc--; argv++;
51c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	}
52c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
53c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	return 0;
54c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger}
55c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
56c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstatic int qfq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
57c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			       struct nlmsghdr *n)
58c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger{
59c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	struct rtattr *tail;
60c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	__u32 tmp;
61c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
62c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	tail = NLMSG_TAIL(n);
63c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
64c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
65c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	while (argc > 0) {
66c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		if (matches(*argv, "weight") == 0) {
67c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			NEXT_ARG();
68c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			if (get_u32(&tmp, *argv, 10)) {
69c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger				explain1("weight"); return -1;
70c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			}
71c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			addattr32(n, 4096, TCA_QFQ_WEIGHT, tmp);
72c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		} else if (matches(*argv, "maxpkt") == 0) {
73c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			NEXT_ARG();
74c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			if (get_u32(&tmp, *argv, 10)) {
75c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger				explain1("maxpkt"); return -1;
76c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			}
77c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			addattr32(n, 4096, TCA_QFQ_LMAX, tmp);
78c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		} else if (strcmp(*argv, "help") == 0) {
79c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			explain_class();
80c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			return -1;
81c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		} else {
82c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			fprintf(stderr, "What is \"%s\"?\n", *argv);
83c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			explain_class();
84c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger			return -1;
85c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		}
86c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		argc--; argv++;
87c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	}
88c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
89c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
90c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
91c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	return 0;
92c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger}
93c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
94c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstatic int qfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
95c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger{
96c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	struct rtattr *tb[TCA_QFQ_MAX + 1];
97c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
98c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	if (opt == NULL)
99c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		return 0;
100c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
101c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	parse_rtattr_nested(tb, TCA_QFQ_MAX, opt);
102c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
103c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	if (tb[TCA_QFQ_WEIGHT]) {
104c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		fprintf(f, "weight %u ",
105ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			rta_getattr_u32(tb[TCA_QFQ_WEIGHT]));
106c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	}
107c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
108c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	if (tb[TCA_QFQ_LMAX]) {
109c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger		fprintf(f, "maxpkt %u ",
110ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			rta_getattr_u32(tb[TCA_QFQ_LMAX]));
111c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	}
112c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
113c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	return 0;
114c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger}
115c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger
116c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemmingerstruct qdisc_util qfq_qdisc_util = {
117c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	.id		= "qfq",
118c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	.parse_qopt	= qfq_parse_opt,
119c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	.print_qopt	= qfq_print_opt,
120c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	.parse_copt	= qfq_parse_class_opt,
121c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger	.print_copt	= qfq_print_opt,
122c441bd4c1be614c022bc7a2b8804ad368d7bb484Stephen Hemminger};
123