On 7/16/18 10:39 AM, Toke Høiland-Jørgensen wrote:
> +static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv,
> +                       struct nlmsghdr *n, const char *dev)
> +{
> +     int unlimited = 0;
> +     __u64 bandwidth = 0;
> +     unsigned interval = 0;
> +     unsigned target = 0;
> +     unsigned diffserv = 0;
> +     unsigned memlimit = 0;
> +     int  overhead = 0;
> +     bool overhead_set = false;
> +     bool overhead_override = false;
> +     int mpu = 0;
> +     int flowmode = -1;
> +     int nat = -1;
> +     int atm = -1;
> +     int autorate = -1;
> +     int wash = -1;
> +     int ingress = -1;
> +     int ack_filter = -1;
> +     struct rtattr *tail;
> +     struct cake_preset *preset, *preset_set = NULL;

For consistency, please use reverse xmas tree like the net code.

> +
> +     while (argc > 0) {
> +             if (strcmp(*argv, "bandwidth") == 0) {
> +                     NEXT_ARG();
> +                     if (get_rate64(&bandwidth, *argv)) {
> +                             fprintf(stderr, "Illegal \"bandwidth\"\n");
> +                             return -1;
> +                     }
> +                     unlimited = 0;
> +                     autorate = 0;
> +             } else if (strcmp(*argv, "unlimited") == 0) {
> +                     bandwidth = 0;
> +                     unlimited = 1;
> +                     autorate = 0;
> +             } else if (strcmp(*argv, "autorate_ingress") == 0) {
> +                     autorate = 1;
> +

for consistency, drop the extra newline.
> +             } else if (strcmp(*argv, "rtt") == 0) {
> +                     NEXT_ARG();
> +                     if (get_time(&interval, *argv)) {
> +                             fprintf(stderr, "Illegal \"rtt\"\n");
> +                             return -1;
> +                     }
> +                     target = interval / 20;
> +                     if(!target)

space between 'if('

> +                             target = 1;
> +             } else if ((preset = find_preset(*argv))) {
> +                     if (preset_set)
> +                             duparg(*argv, preset_set->name);
> +                     preset_set = preset;
> +                     target = preset->target;
> +                     interval = preset->interval;
> +

extra newline here and many more below. Be consistent with the option list.

> +             } else if (strcmp(*argv, "besteffort") == 0) {
> +                     diffserv = CAKE_DIFFSERV_BESTEFFORT;
> +             } else if (strcmp(*argv, "precedence") == 0) {
> +                     diffserv = CAKE_DIFFSERV_PRECEDENCE;
> +             } else if (strcmp(*argv, "diffserv8") == 0) {
> +                     diffserv = CAKE_DIFFSERV_DIFFSERV8;
> +             } else if (strcmp(*argv, "diffserv4") == 0) {
> +                     diffserv = CAKE_DIFFSERV_DIFFSERV4;
> +             } else if (strcmp(*argv, "diffserv") == 0) {
> +                     diffserv = CAKE_DIFFSERV_DIFFSERV4;
> +             } else if (strcmp(*argv, "diffserv3") == 0) {
> +                     diffserv = CAKE_DIFFSERV_DIFFSERV3;
> +
> +             } else if (strcmp(*argv, "nowash") == 0) {
> +                     wash = 0;

...

> +
> +     tail = NLMSG_TAIL(n);
> +     addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
> +     if (bandwidth || unlimited)
> +             addattr_l(n, 1024, TCA_CAKE_BASE_RATE64, &bandwidth, 
> sizeof(bandwidth));
> +     if (diffserv)
> +             addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, 
> sizeof(diffserv));
> +     if (atm != -1)
> +             addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm));
> +     if (flowmode != -1)
> +             addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, 
> sizeof(flowmode));
> +     if (overhead_set)
> +             addattr_l(n, 1024, TCA_CAKE_OVERHEAD, &overhead, 
> sizeof(overhead));
> +     if (overhead_override) {
> +             unsigned zero = 0;
> +             addattr_l(n, 1024, TCA_CAKE_RAW, &zero, sizeof(zero));
> +     }
> +     if (mpu > 0)
> +             addattr_l(n, 1024, TCA_CAKE_MPU, &mpu, sizeof(mpu));
> +     if (interval)
> +             addattr_l(n, 1024, TCA_CAKE_RTT, &interval, sizeof(interval));
> +     if (target)
> +             addattr_l(n, 1024, TCA_CAKE_TARGET, &target, sizeof(target));
> +     if (autorate != -1)
> +             addattr_l(n, 1024, TCA_CAKE_AUTORATE, &autorate, 
> sizeof(autorate));
> +     if (memlimit)
> +             addattr_l(n, 1024, TCA_CAKE_MEMORY, &memlimit, 
> sizeof(memlimit));
> +     if (nat != -1)
> +             addattr_l(n, 1024, TCA_CAKE_NAT, &nat, sizeof(nat));
> +     if (wash != -1)
> +             addattr_l(n, 1024, TCA_CAKE_WASH, &wash, sizeof(wash));
> +     if (ingress != -1)
> +             addattr_l(n, 1024, TCA_CAKE_INGRESS, &ingress, sizeof(ingress));
> +     if (ack_filter != -1)
> +             addattr_l(n, 1024, TCA_CAKE_ACK_FILTER, &ack_filter, 
> sizeof(ack_filter));

there are a number of lines > 80 columns as well. violating for user
messages is fine, but the above needs to be wrapped.

> +
> +     tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
> +     return 0;
> +}
> +
> +

extra newline


> +static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
> +{
> +     struct rtattr *tb[TCA_CAKE_MAX + 1];
> +     __u64 bandwidth = 0;
> +     unsigned diffserv = 0;
> +     unsigned flowmode = 0;
> +     unsigned interval = 0;
> +     unsigned memlimit = 0;
> +     int overhead = 0;
> +     int raw = 0;
> +     int mpu = 0;
> +     int atm = 0;
> +     int nat = 0;
> +     int autorate = 0;
> +     int wash = 0;
> +     int ingress = 0;
> +     int ack_filter = 0;
> +     int split_gso = 0;
> +     SPRINT_BUF(b1);
> +     SPRINT_BUF(b2);
> +
> +     if (opt == NULL)
> +             return 0;
> +
> +     parse_rtattr_nested(tb, TCA_CAKE_MAX, opt);
> +
> +     if (tb[TCA_CAKE_BASE_RATE64] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE64]) >= sizeof(bandwidth)) {
> +             bandwidth = rta_getattr_u64(tb[TCA_CAKE_BASE_RATE64]);
> +             if(bandwidth) {

space between 'if('. There a number of these throughout the file. please
fix them all. I have git am configured to run checkpatch; it tells you
what needs to be fixed.

> +                     print_uint(PRINT_JSON, "bandwidth", NULL, bandwidth);
> +                     print_string(PRINT_FP, NULL, "bandwidth %s ", 
> sprint_rate(bandwidth, b1));
> +             } else
> +                     print_string(PRINT_ANY, "bandwidth", "bandwidth %s ", 
> "unlimited");
> +     }
> +     if (tb[TCA_CAKE_AUTORATE] &&
> +             RTA_PAYLOAD(tb[TCA_CAKE_AUTORATE]) >= sizeof(__u32)) {
> +             autorate = rta_getattr_u32(tb[TCA_CAKE_AUTORATE]);
> +             if(autorate == 1)
> +                     print_string(PRINT_ANY, "autorate", "autorate_%s ", 
> "ingress");
> +             else if(autorate)
> +                     print_string(PRINT_ANY, "autorate", "(?autorate?) ", 
> "unknown");

Why the '(?' and '?)'? here and the diffserv below.

> +     }
> +     if (tb[TCA_CAKE_DIFFSERV_MODE] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) {
> +             diffserv = rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]);
> +             switch(diffserv) {
> +             case CAKE_DIFFSERV_DIFFSERV3:
> +                     print_string(PRINT_ANY, "diffserv", "%s ", "diffserv3");
> +                     break;
> +             case CAKE_DIFFSERV_DIFFSERV4:
> +                     print_string(PRINT_ANY, "diffserv", "%s ", "diffserv4");
> +                     break;
> +             case CAKE_DIFFSERV_DIFFSERV8:
> +                     print_string(PRINT_ANY, "diffserv", "%s ", "diffserv8");
> +                     break;
> +             case CAKE_DIFFSERV_BESTEFFORT:
> +                     print_string(PRINT_ANY, "diffserv", "%s ", 
> "besteffort");
> +                     break;
> +             case CAKE_DIFFSERV_PRECEDENCE:
> +                     print_string(PRINT_ANY, "diffserv", "%s ", 
> "precedence");
> +                     break;
> +             default:
> +                     print_string(PRINT_ANY, "diffserv", "(?diffserv?) ", 
> "unknown");
> +                     break;
> +             };

The diffserv and flowmode below could both be simplified using a helper,
e.g., cake_print_diffsev, and an array of strings indexed by the value.

> +     }
> +     if (tb[TCA_CAKE_FLOW_MODE] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) {
> +             flowmode = rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]);
> +             switch(flowmode) {
> +             case CAKE_FLOW_NONE:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", "flowblind");
> +                     break;
> +             case CAKE_FLOW_SRC_IP:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", "srchost");
> +                     break;
> +             case CAKE_FLOW_DST_IP:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", "dsthost");
> +                     break;
> +             case CAKE_FLOW_HOSTS:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", "hosts");
> +                     break;
> +             case CAKE_FLOW_FLOWS:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", "flows");
> +                     break;
> +             case CAKE_FLOW_DUAL_SRC:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", 
> "dual-srchost");
> +                     break;
> +             case CAKE_FLOW_DUAL_DST:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", 
> "dual-dsthost");
> +                     break;
> +             case CAKE_FLOW_TRIPLE:
> +                     print_string(PRINT_ANY, "flowmode", "%s ", 
> "triple-isolate");
> +                     break;
> +             default:
> +                     print_string(PRINT_ANY, "flowmode", "(?flowmode?) ", 
> "unknown");
> +                     break;
> +             };
> +

extra newline. check the whole file for these.


> +     }
> +
> +     if (tb[TCA_CAKE_NAT] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_NAT]) >= sizeof(__u32)) {
> +         nat = rta_getattr_u32(tb[TCA_CAKE_NAT]);
> +     }
> +
> +     if(nat)
> +             print_string(PRINT_FP, NULL, "nat ", NULL);
> +     print_bool(PRINT_JSON, "nat", NULL, nat);

why is the fp print under the if check but the json one is not? you have
this in a number of places. Why not be consistent in the output?

> +
> +     if (tb[TCA_CAKE_WASH] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_WASH]) >= sizeof(__u32)) {
> +             wash = rta_getattr_u32(tb[TCA_CAKE_WASH]);
> +     }
> +     if (tb[TCA_CAKE_ATM] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) {
> +             atm = rta_getattr_u32(tb[TCA_CAKE_ATM]);
> +     }
> +     if (tb[TCA_CAKE_OVERHEAD] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_OVERHEAD]) >= sizeof(__s32)) {
> +             overhead = *(__s32 *) RTA_DATA(tb[TCA_CAKE_OVERHEAD]);
> +     }
> +     if (tb[TCA_CAKE_MPU] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_MPU]) >= sizeof(__u32)) {
> +             mpu = rta_getattr_u32(tb[TCA_CAKE_MPU]);
> +     }
> +     if (tb[TCA_CAKE_INGRESS] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_INGRESS]) >= sizeof(__u32)) {
> +             ingress = rta_getattr_u32(tb[TCA_CAKE_INGRESS]);
> +     }
> +     if (tb[TCA_CAKE_ACK_FILTER] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_ACK_FILTER]) >= sizeof(__u32)) {
> +             ack_filter = rta_getattr_u32(tb[TCA_CAKE_ACK_FILTER]);
> +     }
> +     if (tb[TCA_CAKE_SPLIT_GSO] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_SPLIT_GSO]) >= sizeof(__u32)) {
> +             split_gso = rta_getattr_u32(tb[TCA_CAKE_SPLIT_GSO]);
> +     }
> +     if (tb[TCA_CAKE_RAW]) {
> +             raw = 1;
> +     }

It would be better to kee this with its use below.

> +     if (tb[TCA_CAKE_RTT] &&
> +         RTA_PAYLOAD(tb[TCA_CAKE_RTT]) >= sizeof(__u32)) {
> +             interval = rta_getattr_u32(tb[TCA_CAKE_RTT]);
> +     }
> +
> +     if (wash)
> +             print_string(PRINT_FP, NULL, "wash ", NULL);
> +     print_bool(PRINT_JSON, "wash", NULL, wash);
> +
> +     if (ingress)
> +             print_string(PRINT_FP, NULL, "ingress ", NULL);
> +     print_bool(PRINT_JSON, "ingress", NULL, ingress);
> +
> +     if (ack_filter == CAKE_ACK_AGGRESSIVE)
> +             print_string(PRINT_ANY, "ack-filter", "ack-filter-%s ", 
> "aggressive");
> +     else if (ack_filter == CAKE_ACK_FILTER)
> +             print_string(PRINT_ANY, "ack-filter", "ack-filter ", "enabled");
> +     else
> +             print_string(PRINT_JSON, "ack-filter", NULL, "disabled");
> +
> +     if (split_gso)
> +             print_string(PRINT_FP, NULL, "split-gso ", NULL);
> +     print_bool(PRINT_JSON, "split_gso", NULL, split_gso);
> +
> +     if (interval)
> +             print_string(PRINT_FP, NULL, "rtt %s ", sprint_time(interval, 
> b2));
> +     print_uint(PRINT_JSON, "rtt", NULL, interval);
> +
> +     if (raw)
> +             print_string(PRINT_FP, NULL, "raw ", NULL);
> +     print_bool(PRINT_JSON, "raw", NULL, raw);
> +
> +     if (atm == CAKE_ATM_ATM)
> +             print_string(PRINT_ANY, "atm", "%s ", "atm");
> +     else if (atm == CAKE_ATM_PTM)
> +             print_string(PRINT_ANY, "atm", "%s ", "ptm");
> +     else if (!raw)
> +             print_string(PRINT_ANY, "atm", "%s ", "noatm");
> +
> +     print_int(PRINT_ANY, "overhead", "overhead %d ", overhead);
> +
> +     if (mpu)
> +             print_uint(PRINT_ANY, "mpu", "mpu %u ", mpu);
> +
> +     if (memlimit) {
> +             print_uint(PRINT_JSON, "memlimit", NULL, memlimit);
> +             print_string(PRINT_FP, NULL, "memlimit %s", 
> sprint_size(memlimit, b1));
> +     }
> +
> +     return 0;
> +}
> +
> +static void cake_print_json_tin(struct rtattr **tstat)
> +{
> +#define PRINT_TSTAT_JSON(type, name, attr) if (tstat[TCA_CAKE_TIN_STATS_ ## 
> attr]) \
> +             print_u64(PRINT_JSON, name, NULL,                       \
> +                     rta_getattr_ ## type((struct rtattr 
> *)tstat[TCA_CAKE_TIN_STATS_ ## attr]))
> +
> +     open_json_object(NULL);
> +     PRINT_TSTAT_JSON(u64, "threshold_rate", THRESHOLD_RATE64);
> +     PRINT_TSTAT_JSON(u64, "sent_bytes", SENT_BYTES64);
> +     PRINT_TSTAT_JSON(u32, "backlog_bytes", BACKLOG_BYTES);
> +     PRINT_TSTAT_JSON(u32, "target_us", TARGET_US);
> +     PRINT_TSTAT_JSON(u32, "interval_us", INTERVAL_US);
> +     PRINT_TSTAT_JSON(u32, "peak_delay_us", PEAK_DELAY_US);
> +     PRINT_TSTAT_JSON(u32, "avg_delay_us", AVG_DELAY_US);
> +     PRINT_TSTAT_JSON(u32, "base_delay_us", BASE_DELAY_US);
> +     PRINT_TSTAT_JSON(u32, "sent_packets", SENT_PACKETS);
> +     PRINT_TSTAT_JSON(u32, "way_indirect_hits", WAY_INDIRECT_HITS);
> +     PRINT_TSTAT_JSON(u32, "way_misses", WAY_MISSES);
> +     PRINT_TSTAT_JSON(u32, "way_collisions", WAY_COLLISIONS);
> +     PRINT_TSTAT_JSON(u32, "drops", DROPPED_PACKETS);
> +     PRINT_TSTAT_JSON(u32, "ecn_mark", ECN_MARKED_PACKETS);
> +     PRINT_TSTAT_JSON(u32, "ack_drops", ACKS_DROPPED_PACKETS);
> +     PRINT_TSTAT_JSON(u32, "sparse_flows", SPARSE_FLOWS);
> +     PRINT_TSTAT_JSON(u32, "bulk_flows", BULK_FLOWS);
> +     PRINT_TSTAT_JSON(u32, "unresponsive_flows", UNRESPONSIVE_FLOWS);
> +     PRINT_TSTAT_JSON(u32, "max_pkt_len", MAX_SKBLEN);
> +     PRINT_TSTAT_JSON(u32, "flow_quantum", FLOW_QUANTUM);
> +     close_json_object();
> +
> +#undef PRINT_TSTAT_JSON
> +}
> +
> +static int cake_print_xstats(struct qdisc_util *qu, FILE *f,
> +                          struct rtattr *xstats)
> +{
> +     SPRINT_BUF(b1);
> +     struct rtattr *st[TCA_CAKE_STATS_MAX + 1];
> +     int i;
> +
> +     if (xstats == NULL)
> +             return 0;
> +
> +#define GET_STAT_U32(attr) rta_getattr_u32(st[TCA_CAKE_STATS_ ## attr])
> +#define GET_STAT_S32(attr) (*(__s32*)RTA_DATA(st[TCA_CAKE_STATS_ ## attr]))
> +#define GET_STAT_U64(attr) rta_getattr_u64(st[TCA_CAKE_STATS_ ## attr])
> +
> +     parse_rtattr_nested(st, TCA_CAKE_STATS_MAX, xstats);
> +
> +     if (st[TCA_CAKE_STATS_MEMORY_USED] &&
> +         st[TCA_CAKE_STATS_MEMORY_LIMIT]) {
> +             print_string(PRINT_FP, NULL, " memory used: %s",
> +                     sprint_size(GET_STAT_U32(MEMORY_USED), b1));
> +
> +             print_string(PRINT_FP, NULL, " of %s\n",
> +                     sprint_size(GET_STAT_U32(MEMORY_LIMIT), b1));
> +
> +             print_uint(PRINT_JSON, "memory_used", NULL,
> +                     GET_STAT_U32(MEMORY_USED));
> +             print_uint(PRINT_JSON, "memory_limit", NULL,
> +                     GET_STAT_U32(MEMORY_LIMIT));
> +     }
> +
> +     if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64]) {
> +             print_string(PRINT_FP, NULL, " capacity estimate: %s\n",
> +                     sprint_rate(GET_STAT_U64(CAPACITY_ESTIMATE64), b1));
> +             print_uint(PRINT_JSON, "capacity_estimate", NULL,
> +                     GET_STAT_U64(CAPACITY_ESTIMATE64));
> +     }
> +
> +     if (st[TCA_CAKE_STATS_MIN_NETLEN] &&
> +         st[TCA_CAKE_STATS_MAX_NETLEN]) {
> +             print_uint(PRINT_ANY, "min_network_size",
> +                        " min/max network layer size: %12u",
> +                        GET_STAT_U32(MIN_NETLEN));
> +             print_uint(PRINT_ANY, "max_network_size",
> +                        " /%8u\n", GET_STAT_U32(MAX_NETLEN));
> +     }
> +
> +     if (st[TCA_CAKE_STATS_MIN_ADJLEN] &&
> +         st[TCA_CAKE_STATS_MAX_ADJLEN]) {
> +             print_uint(PRINT_ANY, "min_adj_size",
> +                        " min/max overhead-adjusted size: %8u",
> +                        GET_STAT_U32(MIN_ADJLEN));
> +             print_uint(PRINT_ANY, "max_adj_size",
> +                        " /%8u\n", GET_STAT_U32(MAX_ADJLEN));
> +     }
> +
> +     if (st[TCA_CAKE_STATS_AVG_NETOFF])
> +             print_uint(PRINT_ANY, "avg_hdr_offset",
> +                        " average network hdr offset: %12u\n\n",
> +                        GET_STAT_U32(AVG_NETOFF));
> +
> +     /* class stats */
> +     if (st[TCA_CAKE_STATS_DEFICIT])
> +             print_int(PRINT_ANY, "deficit", "  deficit %u",
> +                       GET_STAT_S32(DEFICIT));
> +     if (st[TCA_CAKE_STATS_COBALT_COUNT])
> +             print_uint(PRINT_ANY, "count", " count %u",
> +                        GET_STAT_U32(COBALT_COUNT));
> +
> +     if (st[TCA_CAKE_STATS_DROPPING] && GET_STAT_U32(DROPPING)) {
> +             print_bool(PRINT_ANY, "dropping", " dropping", true);
> +             if (st[TCA_CAKE_STATS_DROP_NEXT_US]) {
> +                     int drop_next = GET_STAT_S32(DROP_NEXT_US);
> +                     if (drop_next < 0) {
> +                             print_string(PRINT_FP, NULL, " drop_next -%s",
> +                                     sprint_time(drop_next, b1));
> +                     } else {
> +                             print_uint(PRINT_JSON, "drop_next", NULL,
> +                                     drop_next);
> +                             print_string(PRINT_FP, NULL, " drop_next %s",
> +                                     sprint_time(drop_next, b1));
> +                     }
> +             }
> +     }
> +
> +     if (st[TCA_CAKE_STATS_P_DROP]) {
> +             print_uint(PRINT_ANY, "blue_prob", " blue_prob %u",
> +                        GET_STAT_U32(P_DROP));
> +             if (st[TCA_CAKE_STATS_BLUE_TIMER_US]) {
> +                     int blue_timer = GET_STAT_S32(BLUE_TIMER_US);
> +                     if (blue_timer < 0) {
> +                             print_string(PRINT_FP, NULL, " blue_timer -%s",
> +                                     sprint_time(blue_timer, b1));
> +                     } else {
> +                             print_uint(PRINT_JSON, "blue_timer", NULL,
> +                                     blue_timer);
> +                             print_string(PRINT_FP, NULL, " blue_timer %s",
> +                                     sprint_time(blue_timer, b1));
> +                     }
> +             }
> +     }
> +
> +#undef GET_STAT_U32
> +#undef GET_STAT_S32
> +#undef GET_STAT_U64
> +
> +     if (st[TCA_CAKE_STATS_TIN_STATS]) {
> +             struct rtattr *tins[TC_CAKE_MAX_TINS + 1];
> +             struct rtattr *tstat[TC_CAKE_MAX_TINS][TCA_CAKE_TIN_STATS_MAX + 
> 1];
> +             int num_tins = 0;
> +
> +             parse_rtattr_nested(tins, TC_CAKE_MAX_TINS, 
> st[TCA_CAKE_STATS_TIN_STATS]);
> +
> +             for (i = 1; i <= TC_CAKE_MAX_TINS && tins[i]; i++) {
> +                     parse_rtattr_nested(tstat[i-1], TCA_CAKE_TIN_STATS_MAX, 
> tins[i]);
> +                     num_tins++;
> +             }
> +
> +             if (!num_tins)
> +                     return 0;
> +
> +             if (is_json_context()) {
> +                     open_json_array(PRINT_JSON, "tins");
> +                     for (i = 0; i < num_tins; i++)
> +                             cake_print_json_tin(tstat[i]);
> +                     close_json_array(PRINT_JSON, NULL);
> +
> +                     return 0;
> +             }
> +
> +
> +             switch(num_tins) {
> +             case 3:
> +                     fprintf(f, "                   Bulk  Best Effort        
> Voice\n");
> +                     break;
> +
> +             case 4:
> +                     fprintf(f, "                   Bulk  Best Effort        
> Video        Voice\n");
> +                     break;
> +
> +             default:
> +                     fprintf(f, "          ");
> +                     for(i=0; i < num_tins; i++)
> +                             fprintf(f, "        Tin %u", i);
> +                     fprintf(f, "\n");
> +             };
> +
> +#define GET_TSTAT(i, attr) (tstat[i][TCA_CAKE_TIN_STATS_ ## attr])
> +#define PRINT_TSTAT(name, attr, fmts, val)   do {            \
> +                     if (GET_TSTAT(0, attr)) {               \
> +                             fprintf(f, name);               \
> +                             for (i = 0; i < num_tins; i++)  \
> +                                     fprintf(f, " %12" fmts, val);   \
> +                             fprintf(f, "\n");                       \
> +                     }                                               \
> +             } while (0)
> +
> +#define SPRINT_TSTAT(pfunc, type, name, attr) PRINT_TSTAT(           \
> +                     name, attr, "s", sprint_ ## pfunc(              \
> +                             rta_getattr_ ## type(GET_TSTAT(i, attr)), b1))
> +
> +#define PRINT_TSTAT_U32(name, attr)  PRINT_TSTAT(                    \
> +                     name, attr, "u", rta_getattr_u32(GET_TSTAT(i, attr)))
> +
> +#define PRINT_TSTAT_U64(name, attr)  PRINT_TSTAT(                    \
> +                     name, attr, "llu", rta_getattr_u64(GET_TSTAT(i, attr)))
> +
> +             SPRINT_TSTAT(rate, u64, "  thresh  ", THRESHOLD_RATE64);
> +             SPRINT_TSTAT(time, u32, "  target  ", TARGET_US);
> +             SPRINT_TSTAT(time, u32, "  interval", INTERVAL_US);
> +             SPRINT_TSTAT(time, u32, "  pk_delay", PEAK_DELAY_US);
> +             SPRINT_TSTAT(time, u32, "  av_delay", AVG_DELAY_US);
> +             SPRINT_TSTAT(time, u32, "  sp_delay", BASE_DELAY_US);
> +             SPRINT_TSTAT(size, u32, "  backlog ", BACKLOG_BYTES);
> +
> +             PRINT_TSTAT_U32("  pkts    ", SENT_PACKETS);
> +             PRINT_TSTAT_U64("  bytes   ", SENT_BYTES64);
> +
> +             PRINT_TSTAT_U32("  way_inds", WAY_INDIRECT_HITS);
> +             PRINT_TSTAT_U32("  way_miss", WAY_MISSES);
> +             PRINT_TSTAT_U32("  way_cols", WAY_COLLISIONS);
> +             PRINT_TSTAT_U32("  drops   ", DROPPED_PACKETS);
> +             PRINT_TSTAT_U32("  marks   ", ECN_MARKED_PACKETS);
> +             PRINT_TSTAT_U32("  ack_drop", ACKS_DROPPED_PACKETS);
> +             PRINT_TSTAT_U32("  sp_flows", SPARSE_FLOWS);
> +             PRINT_TSTAT_U32("  bk_flows", BULK_FLOWS);
> +             PRINT_TSTAT_U32("  un_flows", UNRESPONSIVE_FLOWS);
> +             PRINT_TSTAT_U32("  max_len ", MAX_SKBLEN);
> +             PRINT_TSTAT_U32("  quantum ", FLOW_QUANTUM);

I do agree that the above is simpler with macros than expanded into
functions.
_______________________________________________
Cake mailing list
[email protected]
https://lists.bufferbloat.net/listinfo/cake

Reply via email to