libiproute: print_route() always uses stdout, do not pass FILE pointer to it.

libiproute: Use FAST_FUNC

function                                             old     new   delta
iprule_modify                                        884     905     +21
ipaddr_modify                                       1289    1310     +21
rtnl_send                                             53      69     +16
xrtnl_wilddump_request                               109     124     +15
xrtnl_dump_filter                                    394     403      +9
rtnl_talk                                            534     539      +5
print_addrinfo                                      1369    1374      +5
iproute_modify                                      1017    1020      +3
iprule_list                                           81      83      +2
xrtnl_open                                           163     161      -2
parse_rtattr                                          89      87      -2
ipaddr_list_or_flush                                2176    2174      -2
addattr_l                                             91      88      -3
flush_update                                         116     108      -8
iproute_list_or_flush                               1285    1263     -22
iproute_get                                          878     852     -26
print_route                                         1913    1752    -161
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 9/8 up/down: 97/-226)          Total: -129 bytes
This commit is contained in:
Denis Vlasenko 2008-06-29 06:22:40 +00:00
parent 270d5d75f1
commit 0db2c2eb71
3 changed files with 95 additions and 92 deletions

View File

@ -79,9 +79,8 @@ static unsigned get_hz(void)
} }
static int print_route(const struct sockaddr_nl *who ATTRIBUTE_UNUSED, static int print_route(const struct sockaddr_nl *who ATTRIBUTE_UNUSED,
struct nlmsghdr *n, void *arg) struct nlmsghdr *n, void *arg ATTRIBUTE_UNUSED)
{ {
FILE *fp = (FILE*)arg;
struct rtmsg *r = NLMSG_DATA(n); struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len; int len = n->nlmsg_len;
struct rtattr * tb[RTA_MAX+1]; struct rtattr * tb[RTA_MAX+1];
@ -194,73 +193,71 @@ static int print_route(const struct sockaddr_nl *who ATTRIBUTE_UNUSED,
} }
if (n->nlmsg_type == RTM_DELROUTE) { if (n->nlmsg_type == RTM_DELROUTE) {
fprintf(fp, "Deleted "); printf("Deleted ");
} }
if (r->rtm_type != RTN_UNICAST && !filter.type) { if (r->rtm_type != RTN_UNICAST && !filter.type) {
fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
} }
if (tb[RTA_DST]) { if (tb[RTA_DST]) {
if (r->rtm_dst_len != host_len) { if (r->rtm_dst_len != host_len) {
fprintf(fp, "%s/%u ", rt_addr_n2a(r->rtm_family, printf("%s/%u ", rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[RTA_DST]), RTA_PAYLOAD(tb[RTA_DST]),
RTA_DATA(tb[RTA_DST]), RTA_DATA(tb[RTA_DST]),
abuf, sizeof(abuf)), abuf, sizeof(abuf)),
r->rtm_dst_len r->rtm_dst_len
); );
} else { } else {
fprintf(fp, "%s ", format_host(r->rtm_family, printf("%s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_DST]), RTA_PAYLOAD(tb[RTA_DST]),
RTA_DATA(tb[RTA_DST]), RTA_DATA(tb[RTA_DST]),
abuf, sizeof(abuf)) abuf, sizeof(abuf))
); );
} }
} else if (r->rtm_dst_len) { } else if (r->rtm_dst_len) {
fprintf(fp, "0/%d ", r->rtm_dst_len); printf("0/%d ", r->rtm_dst_len);
} else { } else {
fprintf(fp, "default "); printf("default ");
} }
if (tb[RTA_SRC]) { if (tb[RTA_SRC]) {
if (r->rtm_src_len != host_len) { if (r->rtm_src_len != host_len) {
fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family, printf("from %s/%u ", rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[RTA_SRC]), RTA_PAYLOAD(tb[RTA_SRC]),
RTA_DATA(tb[RTA_SRC]), RTA_DATA(tb[RTA_SRC]),
abuf, sizeof(abuf)), abuf, sizeof(abuf)),
r->rtm_src_len r->rtm_src_len
); );
} else { } else {
fprintf(fp, "from %s ", format_host(r->rtm_family, printf("from %s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_SRC]), RTA_PAYLOAD(tb[RTA_SRC]),
RTA_DATA(tb[RTA_SRC]), RTA_DATA(tb[RTA_SRC]),
abuf, sizeof(abuf)) abuf, sizeof(abuf))
); );
} }
} else if (r->rtm_src_len) { } else if (r->rtm_src_len) {
fprintf(fp, "from 0/%u ", r->rtm_src_len); printf("from 0/%u ", r->rtm_src_len);
} }
if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) { if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
fprintf(fp, "via %s ", printf("via %s ", format_host(r->rtm_family,
format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_GATEWAY]), RTA_PAYLOAD(tb[RTA_GATEWAY]),
RTA_DATA(tb[RTA_GATEWAY]), RTA_DATA(tb[RTA_GATEWAY]),
abuf, sizeof(abuf))); abuf, sizeof(abuf)));
} }
if (tb[RTA_OIF] && filter.oifmask != -1) { if (tb[RTA_OIF] && filter.oifmask != -1) {
fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
} }
if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) { if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) {
/* Do not use format_host(). It is our local addr /* Do not use format_host(). It is our local addr
and symbolic name will not be useful. and symbolic name will not be useful.
*/ */
fprintf(fp, " src %s ", printf(" src %s ", rt_addr_n2a(r->rtm_family,
rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[RTA_PREFSRC]), RTA_PAYLOAD(tb[RTA_PREFSRC]),
RTA_DATA(tb[RTA_PREFSRC]), RTA_DATA(tb[RTA_PREFSRC]),
abuf, sizeof(abuf))); abuf, sizeof(abuf)));
} }
if (tb[RTA_PRIORITY]) { if (tb[RTA_PRIORITY]) {
fprintf(fp, " metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
} }
if (r->rtm_family == AF_INET6) { if (r->rtm_family == AF_INET6) {
struct rta_cacheinfo *ci = NULL; struct rta_cacheinfo *ci = NULL;
@ -269,24 +266,23 @@ static int print_route(const struct sockaddr_nl *who ATTRIBUTE_UNUSED,
} }
if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
if (r->rtm_flags & RTM_F_CLONED) { if (r->rtm_flags & RTM_F_CLONED) {
fprintf(fp, "%c cache ", _SL_); printf("%c cache ", _SL_);
} }
if (ci->rta_expires) { if (ci->rta_expires) {
fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); printf(" expires %dsec", ci->rta_expires / get_hz());
} }
if (ci->rta_error != 0) { if (ci->rta_error != 0) {
fprintf(fp, " error %d", ci->rta_error); printf(" error %d", ci->rta_error);
} }
} else if (ci) { } else if (ci) {
if (ci->rta_error != 0) if (ci->rta_error != 0)
fprintf(fp, " error %d", ci->rta_error); printf(" error %d", ci->rta_error);
} }
} }
if (tb[RTA_IIF] && filter.iifmask != -1) { if (tb[RTA_IIF] && filter.iifmask != -1) {
fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
} }
fputc('\n', fp); bb_putchar('\n');
fflush(fp);
return 0; return 0;
} }
@ -331,7 +327,9 @@ USE_FEATURE_IP_RULE(ARG_table,)
req.n.nlmsg_flags = NLM_F_REQUEST | flags; req.n.nlmsg_flags = NLM_F_REQUEST | flags;
req.n.nlmsg_type = cmd; req.n.nlmsg_type = cmd;
req.r.rtm_family = preferred_family; req.r.rtm_family = preferred_family;
if (RT_TABLE_MAIN) /* if it is zero, memset already did it */
req.r.rtm_table = RT_TABLE_MAIN; req.r.rtm_table = RT_TABLE_MAIN;
if (RT_SCOPE_NOWHERE)
req.r.rtm_scope = RT_SCOPE_NOWHERE; req.r.rtm_scope = RT_SCOPE_NOWHERE;
if (cmd != RTM_DELROUTE) { if (cmd != RTM_DELROUTE) {
@ -476,12 +474,15 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family)
nladdr.nl_family = AF_NETLINK; nladdr.nl_family = AF_NETLINK;
req.nlh.nlmsg_len = sizeof(req); req.nlh.nlmsg_len = sizeof(req);
if (RTM_GETROUTE)
req.nlh.nlmsg_type = RTM_GETROUTE; req.nlh.nlmsg_type = RTM_GETROUTE;
if (NLM_F_ROOT | NLM_F_REQUEST)
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST; req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
req.nlh.nlmsg_pid = 0; /*req.nlh.nlmsg_pid = 0; - memset did it already */
req.nlh.nlmsg_seq = rth->dump = ++rth->seq; req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
req.rtm.rtm_family = family; req.rtm.rtm_family = family;
req.rtm.rtm_flags |= RTM_F_CLONED; if (RTM_F_CLONED)
req.rtm.rtm_flags = RTM_F_CLONED;
return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr)); return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
} }
@ -667,7 +668,7 @@ static int iproute_list_or_flush(char **argv, int flush)
for (;;) { for (;;) {
xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
filter.flushed = 0; filter.flushed = 0;
xrtnl_dump_filter(&rth, print_route, stdout); xrtnl_dump_filter(&rth, print_route, NULL);
if (filter.flushed == 0) if (filter.flushed == 0)
return 0; return 0;
if (flush_update()) if (flush_update())
@ -680,7 +681,7 @@ static int iproute_list_or_flush(char **argv, int flush)
} else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
bb_perror_msg_and_die("cannot send dump request"); bb_perror_msg_and_die("cannot send dump request");
} }
xrtnl_dump_filter(&rth, print_route, stdout); xrtnl_dump_filter(&rth, print_route, NULL);
return 0; return 0;
} }
@ -707,16 +708,18 @@ static int iproute_get(char **argv)
iproute_reset_filter(); iproute_reset_filter();
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
if (NLM_F_REQUEST)
req.n.nlmsg_flags = NLM_F_REQUEST; req.n.nlmsg_flags = NLM_F_REQUEST;
if (RTM_GETROUTE)
req.n.nlmsg_type = RTM_GETROUTE; req.n.nlmsg_type = RTM_GETROUTE;
req.r.rtm_family = preferred_family; req.r.rtm_family = preferred_family;
req.r.rtm_table = 0; /*req.r.rtm_table = 0; - memset did this already */
req.r.rtm_protocol = 0; /*req.r.rtm_protocol = 0;*/
req.r.rtm_scope = 0; /*req.r.rtm_scope = 0;*/
req.r.rtm_type = 0; /*req.r.rtm_type = 0;*/
req.r.rtm_src_len = 0; /*req.r.rtm_src_len = 0;*/
req.r.rtm_dst_len = 0; /*req.r.rtm_dst_len = 0;*/
req.r.rtm_tos = 0; /*req.r.rtm_tos = 0;*/
while (*argv) { while (*argv) {
switch (index_in_strings(options, *argv)) { switch (index_in_strings(options, *argv)) {
@ -802,7 +805,7 @@ static int iproute_get(char **argv)
int len = req.n.nlmsg_len; int len = req.n.nlmsg_len;
struct rtattr * tb[RTA_MAX+1]; struct rtattr * tb[RTA_MAX+1];
print_route(NULL, &req.n, (void*)stdout); print_route(NULL, &req.n, NULL);
if (req.n.nlmsg_type != RTM_NEWROUTE) { if (req.n.nlmsg_type != RTM_NEWROUTE) {
bb_error_msg_and_die("not a route?"); bb_error_msg_and_die("not a route?");
@ -837,7 +840,7 @@ static int iproute_get(char **argv)
return 2; return 2;
} }
} }
print_route(NULL, &req.n, (void*)stdout); print_route(NULL, &req.n, NULL);
return 0; return 0;
} }

View File

@ -17,12 +17,12 @@
#include "libbb.h" #include "libbb.h"
#include "libnetlink.h" #include "libnetlink.h"
void rtnl_close(struct rtnl_handle *rth) void FAST_FUNC rtnl_close(struct rtnl_handle *rth)
{ {
close(rth->fd); close(rth->fd);
} }
int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) int FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
{ {
socklen_t addr_len; socklen_t addr_len;
@ -46,7 +46,7 @@ int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
return 0; return 0;
} }
int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
{ {
struct { struct {
struct nlmsghdr nlh; struct nlmsghdr nlh;
@ -68,7 +68,7 @@ int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
(struct sockaddr*)&nladdr, sizeof(nladdr)); (struct sockaddr*)&nladdr, sizeof(nladdr));
} }
int rtnl_send(struct rtnl_handle *rth, char *buf, int len) int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len)
{ {
struct sockaddr_nl nladdr; struct sockaddr_nl nladdr;
@ -78,7 +78,7 @@ int rtnl_send(struct rtnl_handle *rth, char *buf, int len)
return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr)); return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr));
} }
int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
{ {
struct nlmsghdr nlh; struct nlmsghdr nlh;
struct sockaddr_nl nladdr; struct sockaddr_nl nladdr;
@ -194,7 +194,7 @@ static int rtnl_dump_filter(struct rtnl_handle *rth,
return retval; return retval;
} }
int xrtnl_dump_filter(struct rtnl_handle *rth, int FAST_FUNC xrtnl_dump_filter(struct rtnl_handle *rth,
int (*filter)(const struct sockaddr_nl *, struct nlmsghdr *, void *), int (*filter)(const struct sockaddr_nl *, struct nlmsghdr *, void *),
void *arg1) void *arg1)
{ {
@ -204,7 +204,7 @@ int xrtnl_dump_filter(struct rtnl_handle *rth,
return ret; return ret;
} }
int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
pid_t peer, unsigned groups, pid_t peer, unsigned groups,
struct nlmsghdr *answer, struct nlmsghdr *answer,
int (*junk)(struct sockaddr_nl *, struct nlmsghdr *, void *), int (*junk)(struct sockaddr_nl *, struct nlmsghdr *, void *),
@ -332,7 +332,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
return retval; return retval;
} }
int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) int FAST_FUNC addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
{ {
int len = RTA_LENGTH(4); int len = RTA_LENGTH(4);
struct rtattr *rta; struct rtattr *rta;
@ -346,7 +346,7 @@ int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
return 0; return 0;
} }
int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
{ {
int len = RTA_LENGTH(alen); int len = RTA_LENGTH(alen);
struct rtattr *rta; struct rtattr *rta;
@ -361,7 +361,7 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
return 0; return 0;
} }
int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) int FAST_FUNC rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)
{ {
int len = RTA_LENGTH(4); int len = RTA_LENGTH(4);
struct rtattr *subrta; struct rtattr *subrta;
@ -377,7 +377,7 @@ int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)
return 0; return 0;
} }
int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen)
{ {
struct rtattr *subrta; struct rtattr *subrta;
int len = RTA_LENGTH(alen); int len = RTA_LENGTH(alen);
@ -394,7 +394,7 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen
} }
int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) int FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{ {
while (RTA_OK(rta, len)) { while (RTA_OK(rta, len)) {
if (rta->rta_type <= max) { if (rta->rta_type <= max) {

View File

@ -22,13 +22,13 @@ struct rtnl_handle
uint32_t dump; uint32_t dump;
}; };
extern int xrtnl_open(struct rtnl_handle *rth); extern int xrtnl_open(struct rtnl_handle *rth) FAST_FUNC;
extern void rtnl_close(struct rtnl_handle *rth); extern void rtnl_close(struct rtnl_handle *rth) FAST_FUNC;
extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) FAST_FUNC;
extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) FAST_FUNC;
extern int xrtnl_dump_filter(struct rtnl_handle *rth, extern int xrtnl_dump_filter(struct rtnl_handle *rth,
int (*filter)(const struct sockaddr_nl*, struct nlmsghdr *n, void*), int (*filter)(const struct sockaddr_nl*, struct nlmsghdr *n, void*),
void *arg1); void *arg1) FAST_FUNC;
/* bbox doesn't use parameters no. 3, 4, 6, 7, stub them out */ /* bbox doesn't use parameters no. 3, 4, 6, 7, stub them out */
#define rtnl_talk(rtnl, n, peer, groups, answer, junk, jarg) \ #define rtnl_talk(rtnl, n, peer, groups, answer, junk, jarg) \
@ -36,17 +36,17 @@ extern int xrtnl_dump_filter(struct rtnl_handle *rth,
extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
unsigned groups, struct nlmsghdr *answer, unsigned groups, struct nlmsghdr *answer,
int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
void *jarg); void *jarg) FAST_FUNC;
extern int rtnl_send(struct rtnl_handle *rth, char *buf, int); extern int rtnl_send(struct rtnl_handle *rth, char *buf, int) FAST_FUNC;
extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data); extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) FAST_FUNC;
extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen); extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) FAST_FUNC;
extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data); extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) FAST_FUNC;
extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen); extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) FAST_FUNC;
extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len); extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) FAST_FUNC;
#if __GNUC_PREREQ(4,1) #if __GNUC_PREREQ(4,1)
# pragma GCC visibility pop # pragma GCC visibility pop