1 /* 2 * q_drr.c DRR. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Patrick McHardy <kaber (at) trash.net> 10 * 11 */ 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <unistd.h> 16 #include <syslog.h> 17 #include <fcntl.h> 18 #include <sys/socket.h> 19 #include <netinet/in.h> 20 #include <arpa/inet.h> 21 #include <string.h> 22 23 #include "utils.h" 24 #include "tc_util.h" 25 26 static void explain(void) 27 { 28 fprintf(stderr, "Usage: ... drr\n"); 29 } 30 31 static void explain2(void) 32 { 33 fprintf(stderr, "Usage: ... drr quantum SIZE\n"); 34 } 35 36 37 static int drr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) 38 { 39 while (argc) { 40 if (strcmp(*argv, "help") == 0) { 41 explain(); 42 return -1; 43 } else { 44 fprintf(stderr, "What is \"%s\"?\n", *argv); 45 explain(); 46 return -1; 47 } 48 } 49 return 0; 50 } 51 52 static int drr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, 53 struct nlmsghdr *n) 54 { 55 struct rtattr *tail; 56 __u32 tmp; 57 58 tail = NLMSG_TAIL(n); 59 addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 60 61 while (argc > 0) { 62 if (strcmp(*argv, "quantum") == 0) { 63 NEXT_ARG(); 64 if (get_size(&tmp, *argv)) { 65 fprintf(stderr, "Illegal \"quantum\"\n"); 66 return -1; 67 } 68 addattr_l(n, 1024, TCA_DRR_QUANTUM, &tmp, sizeof(tmp)); 69 } else if (strcmp(*argv, "help") == 0) { 70 explain2(); 71 return -1; 72 } else { 73 fprintf(stderr, "What is \"%s\"?\n", *argv); 74 explain2(); 75 return -1; 76 } 77 argc--; argv++; 78 } 79 80 tail->rta_len = (void *) NLMSG_TAIL(n) - (void *)tail; 81 return 0; 82 } 83 84 static int drr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 85 { 86 struct rtattr *tb[TCA_DRR_MAX + 1]; 87 SPRINT_BUF(b1); 88 89 if (opt == NULL) 90 return 0; 91 92 parse_rtattr_nested(tb, TCA_DRR_MAX, opt); 93 94 if (tb[TCA_DRR_QUANTUM]) 95 fprintf(f, "quantum %s ", 96 sprint_size(rta_getattr_u32(tb[TCA_DRR_QUANTUM]), b1)); 97 return 0; 98 } 99 100 static int drr_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) 101 { 102 struct tc_drr_stats *x; 103 SPRINT_BUF(b1); 104 105 if (xstats == NULL) 106 return 0; 107 if (RTA_PAYLOAD(xstats) < sizeof(*x)) 108 return -1; 109 x = RTA_DATA(xstats); 110 111 fprintf(f, " deficit %s ", sprint_size(x->deficit, b1)); 112 return 0; 113 } 114 115 struct qdisc_util drr_qdisc_util = { 116 .id = "drr", 117 .parse_qopt = drr_parse_opt, 118 .print_qopt = drr_print_opt, 119 .print_xstats = drr_print_xstats, 120 .parse_copt = drr_parse_class_opt, 121 .print_copt = drr_print_opt, 122 }; 123