mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-15 22:15:13 +08:00
8589eb4efd
Every tool in the iproute2 package have one or more function to show an help message to the user. Some of these functions print the help line by line with a series of printf call, e.g. ip/xfrm_state.c does 60 fprintf calls. If we group all the calls to a single one and just concatenate strings, we save a lot of libc calls and thus object size. The size difference of the compiled binaries calculated with bloat-o-meter is: ip/ip: add/remove: 0/0 grow/shrink: 5/15 up/down: 103/-4796 (-4693) Total: Before=672591, After=667898, chg -0.70% ip/rtmon: add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-54 (-54) Total: Before=48879, After=48825, chg -0.11% tc/tc: add/remove: 0/2 grow/shrink: 31/10 up/down: 882/-6133 (-5251) Total: Before=351912, After=346661, chg -1.49% bridge/bridge: add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-459 (-459) Total: Before=70502, After=70043, chg -0.65% misc/lnstat: add/remove: 0/1 grow/shrink: 1/0 up/down: 48/-486 (-438) Total: Before=9960, After=9522, chg -4.40% tipc/tipc: add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-62 (-44) Total: Before=79182, After=79138, chg -0.06% While at it, indent some strings which were starting at column 0, and use tabs where possible, to have a consistent style across helps. Signed-off-by: Matteo Croce <mcroce@redhat.com> Signed-off-by: David Ahern <dsahern@gmail.com>
186 lines
4.2 KiB
C
186 lines
4.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* f_tcindex.c Traffic control index filter
|
|
*
|
|
* Written 1998,1999 by Werner Almesberger
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include "utils.h"
|
|
#include "tc_util.h"
|
|
|
|
static void explain(void)
|
|
{
|
|
fprintf(stderr,
|
|
" Usage: ... tcindex [ hash SIZE ] [ mask MASK ] [ shift SHIFT ]\n"
|
|
" [ pass_on | fall_through ]\n"
|
|
" [ classid CLASSID ] [ action ACTION_SPEC ]\n");
|
|
}
|
|
|
|
static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
|
|
char **argv, struct nlmsghdr *n)
|
|
{
|
|
struct tcmsg *t = NLMSG_DATA(n);
|
|
struct rtattr *tail;
|
|
char *end;
|
|
|
|
if (handle) {
|
|
t->tcm_handle = strtoul(handle, &end, 0);
|
|
if (*end) {
|
|
fprintf(stderr, "Illegal filter ID\n");
|
|
return -1;
|
|
}
|
|
}
|
|
if (!argc) return 0;
|
|
tail = addattr_nest(n, 4096, TCA_OPTIONS);
|
|
while (argc) {
|
|
if (!strcmp(*argv, "hash")) {
|
|
int hash;
|
|
|
|
NEXT_ARG();
|
|
hash = strtoul(*argv, &end, 0);
|
|
if (*end || !hash || hash > 0x10000) {
|
|
explain();
|
|
return -1;
|
|
}
|
|
addattr_l(n, 4096, TCA_TCINDEX_HASH, &hash,
|
|
sizeof(hash));
|
|
} else if (!strcmp(*argv,"mask")) {
|
|
__u16 mask;
|
|
|
|
NEXT_ARG();
|
|
mask = strtoul(*argv, &end, 0);
|
|
if (*end) {
|
|
explain();
|
|
return -1;
|
|
}
|
|
addattr_l(n, 4096, TCA_TCINDEX_MASK, &mask,
|
|
sizeof(mask));
|
|
} else if (!strcmp(*argv,"shift")) {
|
|
int shift;
|
|
|
|
NEXT_ARG();
|
|
shift = strtoul(*argv, &end, 0);
|
|
if (*end) {
|
|
explain();
|
|
return -1;
|
|
}
|
|
addattr_l(n, 4096, TCA_TCINDEX_SHIFT, &shift,
|
|
sizeof(shift));
|
|
} else if (!strcmp(*argv,"fall_through")) {
|
|
int value = 1;
|
|
|
|
addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
|
|
sizeof(value));
|
|
} else if (!strcmp(*argv,"pass_on")) {
|
|
int value = 0;
|
|
|
|
addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
|
|
sizeof(value));
|
|
} else if (!strcmp(*argv,"classid")) {
|
|
__u32 handle;
|
|
|
|
NEXT_ARG();
|
|
if (get_tc_classid(&handle, *argv)) {
|
|
fprintf(stderr, "Illegal \"classid\"\n");
|
|
return -1;
|
|
}
|
|
addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4);
|
|
} else if (!strcmp(*argv,"police")) {
|
|
NEXT_ARG();
|
|
if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) {
|
|
fprintf(stderr, "Illegal \"police\"\n");
|
|
return -1;
|
|
}
|
|
continue;
|
|
} else if (!strcmp(*argv,"action")) {
|
|
NEXT_ARG();
|
|
if (parse_action(&argc, &argv, TCA_TCINDEX_ACT, n)) {
|
|
fprintf(stderr, "Illegal \"action\"\n");
|
|
return -1;
|
|
}
|
|
continue;
|
|
} else {
|
|
explain();
|
|
return -1;
|
|
}
|
|
argc--;
|
|
argv++;
|
|
}
|
|
addattr_nest_end(n, tail);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int tcindex_print_opt(struct filter_util *qu, FILE *f,
|
|
struct rtattr *opt, __u32 handle)
|
|
{
|
|
struct rtattr *tb[TCA_TCINDEX_MAX+1];
|
|
|
|
if (opt == NULL)
|
|
return 0;
|
|
|
|
parse_rtattr_nested(tb, TCA_TCINDEX_MAX, opt);
|
|
|
|
if (handle != ~0) fprintf(f, "handle 0x%04x ", handle);
|
|
if (tb[TCA_TCINDEX_HASH]) {
|
|
__u16 hash;
|
|
|
|
if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH]) < sizeof(hash))
|
|
return -1;
|
|
hash = rta_getattr_u16(tb[TCA_TCINDEX_HASH]);
|
|
fprintf(f, "hash %d ", hash);
|
|
}
|
|
if (tb[TCA_TCINDEX_MASK]) {
|
|
__u16 mask;
|
|
|
|
if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK]) < sizeof(mask))
|
|
return -1;
|
|
mask = rta_getattr_u16(tb[TCA_TCINDEX_MASK]);
|
|
fprintf(f, "mask 0x%04x ", mask);
|
|
}
|
|
if (tb[TCA_TCINDEX_SHIFT]) {
|
|
int shift;
|
|
|
|
if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT]) < sizeof(shift))
|
|
return -1;
|
|
shift = rta_getattr_u32(tb[TCA_TCINDEX_SHIFT]);
|
|
fprintf(f, "shift %d ", shift);
|
|
}
|
|
if (tb[TCA_TCINDEX_FALL_THROUGH]) {
|
|
int fall_through;
|
|
|
|
if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH]) <
|
|
sizeof(fall_through))
|
|
return -1;
|
|
fall_through = rta_getattr_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
|
|
fprintf(f, fall_through ? "fall_through " : "pass_on ");
|
|
}
|
|
if (tb[TCA_TCINDEX_CLASSID]) {
|
|
SPRINT_BUF(b1);
|
|
fprintf(f, "classid %s ", sprint_tc_classid(*(__u32 *)
|
|
RTA_DATA(tb[TCA_TCINDEX_CLASSID]), b1));
|
|
}
|
|
if (tb[TCA_TCINDEX_POLICE]) {
|
|
fprintf(f, "\n");
|
|
tc_print_police(f, tb[TCA_TCINDEX_POLICE]);
|
|
}
|
|
if (tb[TCA_TCINDEX_ACT]) {
|
|
fprintf(f, "\n");
|
|
tc_print_action(f, tb[TCA_TCINDEX_ACT], 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct filter_util tcindex_filter_util = {
|
|
.id = "tcindex",
|
|
.parse_fopt = tcindex_parse_opt,
|
|
.print_fopt = tcindex_print_opt,
|
|
};
|