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