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