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 #define usage() return(-1) 37 38 static int drr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) 39 { 40 while (argc > 0) { 41 if (strcmp(*argv, "help") == 0) { 42 explain(); 43 return -1; 44 } else { 45 fprintf(stderr, "What is \"%s\"?\n", *argv); 46 explain(); 47 return -1; 48 } 49 argc--; argv++; 50 } 51 return 0; 52 } 53 54 static int drr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, 55 struct nlmsghdr *n) 56 { 57 struct rtattr *tail; 58 __u32 tmp; 59 60 tail = NLMSG_TAIL(n); 61 addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 62 63 while (argc > 0) { 64 if (strcmp(*argv, "quantum") == 0) { 65 NEXT_ARG(); 66 if (get_size(&tmp, *argv)) { 67 fprintf(stderr, "Illegal \"quantum\"\n"); 68 return -1; 69 } 70 addattr_l(n, 1024, TCA_DRR_QUANTUM, &tmp, sizeof(tmp)); 71 } else if (strcmp(*argv, "help") == 0) { 72 explain2(); 73 return -1; 74 } else { 75 fprintf(stderr, "What is \"%s\"?\n", *argv); 76 explain2(); 77 return -1; 78 } 79 argc--; argv++; 80 } 81 82 tail->rta_len = (void *) NLMSG_TAIL(n) - (void *)tail; 83 return 0; 84 } 85 86 static int drr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 87 { 88 struct rtattr *tb[TCA_DRR_MAX + 1]; 89 SPRINT_BUF(b1); 90 91 if (opt == NULL) 92 return 0; 93 94 parse_rtattr_nested(tb, TCA_DRR_MAX, opt); 95 96 if (tb[TCA_DRR_QUANTUM]) 97 fprintf(f, "quantum %s ", 98 sprint_size(*(__u32 *)RTA_DATA(tb[TCA_DRR_QUANTUM]), b1)); 99 return 0; 100 } 101 102 static int drr_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) 103 { 104 struct tc_drr_stats *x; 105 SPRINT_BUF(b1); 106 107 if (xstats == NULL) 108 return 0; 109 if (RTA_PAYLOAD(xstats) < sizeof(*x)) 110 return -1; 111 x = RTA_DATA(xstats); 112 113 fprintf(f, " deficit %s ", sprint_size(x->deficit, b1)); 114 return 0; 115 } 116 117 struct qdisc_util drr_qdisc_util = { 118 .id = "drr", 119 .parse_qopt = drr_parse_opt, 120 .print_qopt = drr_print_opt, 121 .print_xstats = drr_print_xstats, 122 .parse_copt = drr_parse_class_opt, 123 .print_copt = drr_print_opt, 124 }; 125