diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-01-04 10:27:51 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-01-04 10:27:51 +0100 |
| commit | a034cab0952bcb93cfbe8b2a333c59615dfa7e90 (patch) | |
| tree | 12ff6f5f3f4bece88ab4dda732d5d6b2fbd3930a /networking | |
| parent | d75f9081d4a0e76bf4118232de3aef80116d5e0f (diff) | |
| download | busybox-w32-a034cab0952bcb93cfbe8b2a333c59615dfa7e90.tar.gz busybox-w32-a034cab0952bcb93cfbe8b2a333c59615dfa7e90.tar.bz2 busybox-w32-a034cab0952bcb93cfbe8b2a333c59615dfa7e90.zip | |
tc: enables this applet
function old new delta
tc_main - 946 +946
cbq_print_opt - 517 +517
print_qdisc - 475 +475
print_class - 359 +359
llproto_names - 264 +264
packed_usage 31853 32066 +213
ll_proto_a2n - 112 +112
llproto_ids - 86 +86
print_tc_classid - 82 +82
static.objects - 20 +20
static._q_ - 16 +16
applet_main 1564 1568 +4
print_filter - 3 +3
applet_names 2708 2711 +3
------------------------------------------------------------------------------
(add/remove: 13/0 grow/shrink: 3/0 up/down: 3100/0) Total: 3100 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking')
| -rw-r--r-- | networking/tc.c | 106 |
1 files changed, 75 insertions, 31 deletions
diff --git a/networking/tc.c b/networking/tc.c index 23abf636c..4e375a066 100644 --- a/networking/tc.c +++ b/networking/tc.c | |||
| @@ -6,22 +6,20 @@ | |||
| 6 | * | 6 | * |
| 7 | * Bernhard Reutner-Fischer adjusted for busybox | 7 | * Bernhard Reutner-Fischer adjusted for busybox |
| 8 | */ | 8 | */ |
| 9 | //config:config TC | ||
| 10 | //config: bool "tc (3.1 kb)" | ||
| 11 | //config: default y | ||
| 12 | //config: help | ||
| 13 | //config: Show / manipulate traffic control settings | ||
| 14 | //config: | ||
| 15 | //config:config FEATURE_TC_INGRESS | ||
| 16 | //config: bool "Enable ingress" | ||
| 17 | //config: default y | ||
| 18 | //config: depends on TC | ||
| 9 | 19 | ||
| 10 | /* Was disabled in 2008 by Bernhard, not known why. | 20 | //applet:IF_TC(APPLET(tc, BB_DIR_SBIN, BB_SUID_DROP)) |
| 11 | --//config:#config TC | 21 | |
| 12 | --//config:# bool "tc" | 22 | //kbuild:lib-$(CONFIG_TC) += tc.o |
| 13 | --//config:# default y | ||
| 14 | --//config:# help | ||
| 15 | --//config:# Show / manipulate traffic control settings | ||
| 16 | --//config:# | ||
| 17 | --//config:#config FEATURE_TC_INGRESS | ||
| 18 | --//config:# default y | ||
| 19 | --//config:# depends on TC | ||
| 20 | -- | ||
| 21 | --//applet:IF_TC(APPLET(tc, BB_DIR_SBIN, BB_SUID_DROP)) | ||
| 22 | -- | ||
| 23 | --//kbuild:lib-$(CONFIG_TC) += tc.o | ||
| 24 | */ | ||
| 25 | 23 | ||
| 26 | //usage:#define tc_trivial_usage | 24 | //usage:#define tc_trivial_usage |
| 27 | /* //usage: "[OPTIONS] OBJECT CMD [dev STRING]" */ | 25 | /* //usage: "[OPTIONS] OBJECT CMD [dev STRING]" */ |
| @@ -52,6 +50,17 @@ | |||
| 52 | #include "libiproute/rt_names.h" | 50 | #include "libiproute/rt_names.h" |
| 53 | #include <linux/pkt_sched.h> /* for the TC_H_* macros */ | 51 | #include <linux/pkt_sched.h> /* for the TC_H_* macros */ |
| 54 | 52 | ||
| 53 | /* This is the deprecated multiqueue interface */ | ||
| 54 | #ifndef TCA_PRIO_MAX | ||
| 55 | enum | ||
| 56 | { | ||
| 57 | TCA_PRIO_UNSPEC, | ||
| 58 | TCA_PRIO_MQ, | ||
| 59 | __TCA_PRIO_MAX | ||
| 60 | }; | ||
| 61 | #define TCA_PRIO_MAX (__TCA_PRIO_MAX - 1) | ||
| 62 | #endif | ||
| 63 | |||
| 55 | #define parse_rtattr_nested(tb, max, rta) \ | 64 | #define parse_rtattr_nested(tb, max, rta) \ |
| 56 | (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) | 65 | (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) |
| 57 | 66 | ||
| @@ -184,11 +193,13 @@ static void print_rate(char *buf, int len, uint32_t rate) | |||
| 184 | } | 193 | } |
| 185 | } | 194 | } |
| 186 | 195 | ||
| 196 | #if 0 | ||
| 187 | /* This is "pfifo_fast". */ | 197 | /* This is "pfifo_fast". */ |
| 188 | static int prio_parse_opt(int argc, char **argv, struct nlmsghdr *n) | 198 | static int prio_parse_opt(int argc, char **argv, struct nlmsghdr *n) |
| 189 | { | 199 | { |
| 190 | return 0; | 200 | return 0; |
| 191 | } | 201 | } |
| 202 | #endif | ||
| 192 | static int prio_print_opt(struct rtattr *opt) | 203 | static int prio_print_opt(struct rtattr *opt) |
| 193 | { | 204 | { |
| 194 | int i; | 205 | int i; |
| @@ -211,11 +222,13 @@ static int prio_print_opt(struct rtattr *opt) | |||
| 211 | return 0; | 222 | return 0; |
| 212 | } | 223 | } |
| 213 | 224 | ||
| 225 | #if 0 | ||
| 214 | /* Class Based Queue */ | 226 | /* Class Based Queue */ |
| 215 | static int cbq_parse_opt(int argc, char **argv, struct nlmsghdr *n) | 227 | static int cbq_parse_opt(int argc, char **argv, struct nlmsghdr *n) |
| 216 | { | 228 | { |
| 217 | return 0; | 229 | return 0; |
| 218 | } | 230 | } |
| 231 | #endif | ||
| 219 | static int cbq_print_opt(struct rtattr *opt) | 232 | static int cbq_print_opt(struct rtattr *opt) |
| 220 | { | 233 | { |
| 221 | struct rtattr *tb[TCA_CBQ_MAX+1]; | 234 | struct rtattr *tb[TCA_CBQ_MAX+1]; |
| @@ -308,8 +321,10 @@ static int cbq_print_opt(struct rtattr *opt) | |||
| 308 | return 0; | 321 | return 0; |
| 309 | } | 322 | } |
| 310 | 323 | ||
| 311 | static int print_qdisc(const struct sockaddr_nl *who UNUSED_PARAM, | 324 | static FAST_FUNC int print_qdisc( |
| 312 | struct nlmsghdr *hdr, void *arg UNUSED_PARAM) | 325 | const struct sockaddr_nl *who UNUSED_PARAM, |
| 326 | struct nlmsghdr *hdr, | ||
| 327 | void *arg UNUSED_PARAM) | ||
| 313 | { | 328 | { |
| 314 | struct tcmsg *msg = NLMSG_DATA(hdr); | 329 | struct tcmsg *msg = NLMSG_DATA(hdr); |
| 315 | int len = hdr->nlmsg_len; | 330 | int len = hdr->nlmsg_len; |
| @@ -364,8 +379,10 @@ static int print_qdisc(const struct sockaddr_nl *who UNUSED_PARAM, | |||
| 364 | return 0; | 379 | return 0; |
| 365 | } | 380 | } |
| 366 | 381 | ||
| 367 | static int print_class(const struct sockaddr_nl *who UNUSED_PARAM, | 382 | static FAST_FUNC int print_class( |
| 368 | struct nlmsghdr *hdr, void *arg UNUSED_PARAM) | 383 | const struct sockaddr_nl *who UNUSED_PARAM, |
| 384 | struct nlmsghdr *hdr, | ||
| 385 | void *arg UNUSED_PARAM) | ||
| 369 | { | 386 | { |
| 370 | struct tcmsg *msg = NLMSG_DATA(hdr); | 387 | struct tcmsg *msg = NLMSG_DATA(hdr); |
| 371 | int len = hdr->nlmsg_len; | 388 | int len = hdr->nlmsg_len; |
| @@ -432,8 +449,10 @@ static int print_class(const struct sockaddr_nl *who UNUSED_PARAM, | |||
| 432 | return 0; | 449 | return 0; |
| 433 | } | 450 | } |
| 434 | 451 | ||
| 435 | static int print_filter(const struct sockaddr_nl *who UNUSED_PARAM, | 452 | static FAST_FUNC int print_filter( |
| 436 | struct nlmsghdr *hdr, void *arg UNUSED_PARAM) | 453 | const struct sockaddr_nl *who UNUSED_PARAM, |
| 454 | struct nlmsghdr *hdr UNUSED_PARAM, | ||
| 455 | void *arg UNUSED_PARAM) | ||
| 437 | { | 456 | { |
| 438 | return 0; | 457 | return 0; |
| 439 | } | 458 | } |
| @@ -451,6 +470,12 @@ int tc_main(int argc UNUSED_PARAM, char **argv) | |||
| 451 | "replace\0" | 470 | "replace\0" |
| 452 | "show\0""list\0" | 471 | "show\0""list\0" |
| 453 | ; | 472 | ; |
| 473 | enum { | ||
| 474 | CMD_add = 0, CMD_del, CMD_change, | ||
| 475 | CMD_link, | ||
| 476 | CMD_replace, | ||
| 477 | CMD_show | ||
| 478 | }; | ||
| 454 | static const char args[] ALIGN1 = | 479 | static const char args[] ALIGN1 = |
| 455 | "dev\0" /* qdisc, class, filter */ | 480 | "dev\0" /* qdisc, class, filter */ |
| 456 | "root\0" /* class, filter */ | 481 | "root\0" /* class, filter */ |
| @@ -460,9 +485,15 @@ int tc_main(int argc UNUSED_PARAM, char **argv) | |||
| 460 | "classid\0" /* change: for class use "handle" */ | 485 | "classid\0" /* change: for class use "handle" */ |
| 461 | "preference\0""priority\0""protocol\0" /* filter */ | 486 | "preference\0""priority\0""protocol\0" /* filter */ |
| 462 | ; | 487 | ; |
| 463 | enum { CMD_add = 0, CMD_del, CMD_change, CMD_link, CMD_replace, CMD_show }; | 488 | enum { |
| 464 | enum { ARG_dev = 0, ARG_root, ARG_parent, ARG_qdisc, | 489 | ARG_dev = 0, |
| 465 | ARG_handle, ARG_classid, ARG_pref, ARG_prio, ARG_proto}; | 490 | ARG_root, |
| 491 | ARG_parent, | ||
| 492 | ARG_qdisc, | ||
| 493 | ARG_handle, | ||
| 494 | ARG_classid, | ||
| 495 | ARG_pref, ARG_prio, ARG_proto | ||
| 496 | }; | ||
| 466 | struct rtnl_handle rth; | 497 | struct rtnl_handle rth; |
| 467 | struct tcmsg msg; | 498 | struct tcmsg msg; |
| 468 | int ret, obj, cmd, arg; | 499 | int ret, obj, cmd, arg; |
| @@ -487,9 +518,12 @@ int tc_main(int argc UNUSED_PARAM, char **argv) | |||
| 487 | invarg_1_to_2(*argv, argv[-1]); | 518 | invarg_1_to_2(*argv, argv[-1]); |
| 488 | argv++; | 519 | argv++; |
| 489 | } | 520 | } |
| 521 | |||
| 490 | memset(&msg, 0, sizeof(msg)); | 522 | memset(&msg, 0, sizeof(msg)); |
| 491 | msg.tcm_family = AF_UNSPEC; | 523 | if (AF_UNSPEC != 0) |
| 524 | msg.tcm_family = AF_UNSPEC; | ||
| 492 | ll_init_map(&rth); | 525 | ll_init_map(&rth); |
| 526 | |||
| 493 | while (*argv) { | 527 | while (*argv) { |
| 494 | arg = index_in_substrings(args, *argv); | 528 | arg = index_in_substrings(args, *argv); |
| 495 | if (arg == ARG_dev) { | 529 | if (arg == ARG_dev) { |
| @@ -526,7 +560,8 @@ int tc_main(int argc UNUSED_PARAM, char **argv) | |||
| 526 | msg.tcm_parent = TC_H_ROOT; | 560 | msg.tcm_parent = TC_H_ROOT; |
| 527 | if (obj == OBJ_filter) | 561 | if (obj == OBJ_filter) |
| 528 | filter_parent = TC_H_ROOT; | 562 | filter_parent = TC_H_ROOT; |
| 529 | } else if (arg == ARG_parent) { | 563 | } else |
| 564 | if (arg == ARG_parent) { | ||
| 530 | uint32_t handle; | 565 | uint32_t handle; |
| 531 | if (msg.tcm_parent) | 566 | if (msg.tcm_parent) |
| 532 | duparg(*argv, "parent"); | 567 | duparg(*argv, "parent"); |
| @@ -535,23 +570,31 @@ int tc_main(int argc UNUSED_PARAM, char **argv) | |||
| 535 | msg.tcm_parent = handle; | 570 | msg.tcm_parent = handle; |
| 536 | if (obj == OBJ_filter) | 571 | if (obj == OBJ_filter) |
| 537 | filter_parent = handle; | 572 | filter_parent = handle; |
| 538 | } else if (arg == ARG_handle) { /* filter::list */ | 573 | } else |
| 574 | if (arg == ARG_handle) { /* filter::list */ | ||
| 539 | if (msg.tcm_handle) | 575 | if (msg.tcm_handle) |
| 540 | duparg(*argv, "handle"); | 576 | duparg(*argv, "handle"); |
| 541 | /* reject LONG_MIN || LONG_MAX */ | 577 | /* reject LONG_MIN || LONG_MAX */ |
| 542 | /* TODO: for fw | 578 | /* TODO: for fw |
| 543 | slash = strchr(handle, '/'); | 579 | slash = strchr(handle, '/'); |
| 544 | if (slash != NULL) | 580 | if (slash != NULL) |
| 545 | *slash = '\0'; | 581 | *slash = '\0'; |
| 546 | */ | 582 | */ |
| 547 | msg.tcm_handle = get_u32(*argv, "handle"); | 583 | msg.tcm_handle = get_u32(*argv, "handle"); |
| 548 | /* if (slash) {if (get_u32(uint32_t &mask, slash+1, NULL)) inv mask; addattr32(n, MAX_MSG, TCA_FW_MASK, mask); */ | 584 | /* if (slash) {if (get_u32(uint32_t &mask, slash+1, NULL)) inv mask; addattr32(n, MAX_MSG, TCA_FW_MASK, mask); */ |
| 549 | } else if (arg == ARG_classid && obj == OBJ_class && cmd == CMD_change){ | 585 | } else |
| 550 | } else if (arg == ARG_pref || arg == ARG_prio) { /* filter::list */ | 586 | if (arg == ARG_classid |
| 587 | && obj == OBJ_class | ||
| 588 | && cmd == CMD_change | ||
| 589 | ) { | ||
| 590 | /* TODO */ | ||
| 591 | } else | ||
| 592 | if (arg == ARG_pref || arg == ARG_prio) { /* filter::list */ | ||
| 551 | if (filter_prio) | 593 | if (filter_prio) |
| 552 | duparg(*argv, "priority"); | 594 | duparg(*argv, "priority"); |
| 553 | filter_prio = get_u32(*argv, "priority"); | 595 | filter_prio = get_u32(*argv, "priority"); |
| 554 | } else if (arg == ARG_proto) { /* filter::list */ | 596 | } else |
| 597 | if (arg == ARG_proto) { /* filter::list */ | ||
| 555 | uint16_t tmp; | 598 | uint16_t tmp; |
| 556 | if (filter_proto) | 599 | if (filter_proto) |
| 557 | duparg(*argv, "protocol"); | 600 | duparg(*argv, "protocol"); |
| @@ -560,6 +603,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv) | |||
| 560 | filter_proto = tmp; | 603 | filter_proto = tmp; |
| 561 | } | 604 | } |
| 562 | } | 605 | } |
| 606 | |||
| 563 | if (cmd >= CMD_show) { /* show or list */ | 607 | if (cmd >= CMD_show) { /* show or list */ |
| 564 | if (obj == OBJ_filter) | 608 | if (obj == OBJ_filter) |
| 565 | msg.tcm_info = TC_H_MAKE(filter_prio<<16, filter_proto); | 609 | msg.tcm_info = TC_H_MAKE(filter_prio<<16, filter_proto); |
