mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-15 05:55:11 +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>
219 lines
5.4 KiB
C
219 lines
5.4 KiB
C
/*
|
|
* link_vti6.c VTI driver module
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
* Authors: Herbert Xu <herbert@gondor.apana.org.au>
|
|
* Saurabh Mohan <saurabh.mohan@vyatta.com> Modified link_gre.c for VTI
|
|
* Steffen Klassert <steffen.klassert@secunet.com> Modified link_vti.c for IPv6
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <net/if.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
|
|
#include <linux/ip.h>
|
|
#include <linux/if_tunnel.h>
|
|
#include "rt_names.h"
|
|
#include "utils.h"
|
|
#include "ip_common.h"
|
|
#include "tunnel.h"
|
|
|
|
static void vti6_print_help(struct link_util *lu, int argc, char **argv,
|
|
FILE *f)
|
|
{
|
|
fprintf(f,
|
|
"Usage: ... %-4s [ remote ADDR ]\n"
|
|
" [ local ADDR ]\n"
|
|
" [ [i|o]key KEY ]\n"
|
|
" [ dev PHYS_DEV ]\n"
|
|
" [ fwmark MARK ]\n"
|
|
"\n"
|
|
"Where: ADDR := { IPV6_ADDRESS }\n"
|
|
" KEY := { DOTTED_QUAD | NUMBER }\n"
|
|
" MARK := { 0x0..0xffffffff }\n",
|
|
lu->id);
|
|
}
|
|
|
|
static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
|
|
struct nlmsghdr *n)
|
|
{
|
|
struct ifinfomsg *ifi = NLMSG_DATA(n);
|
|
struct {
|
|
struct nlmsghdr n;
|
|
struct ifinfomsg i;
|
|
} req = {
|
|
.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
|
|
.n.nlmsg_flags = NLM_F_REQUEST,
|
|
.n.nlmsg_type = RTM_GETLINK,
|
|
.i.ifi_family = preferred_family,
|
|
.i.ifi_index = ifi->ifi_index,
|
|
};
|
|
struct nlmsghdr *answer;
|
|
struct rtattr *tb[IFLA_MAX + 1];
|
|
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
|
|
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
|
|
__be32 ikey = 0;
|
|
__be32 okey = 0;
|
|
inet_prefix saddr, daddr;
|
|
unsigned int link = 0;
|
|
__u32 fwmark = 0;
|
|
int len;
|
|
|
|
inet_prefix_reset(&saddr);
|
|
inet_prefix_reset(&daddr);
|
|
|
|
if (!(n->nlmsg_flags & NLM_F_CREATE)) {
|
|
const struct rtattr *rta;
|
|
|
|
if (rtnl_talk(&rth, &req.n, &answer) < 0) {
|
|
get_failed:
|
|
fprintf(stderr,
|
|
"Failed to get existing tunnel info.\n");
|
|
return -1;
|
|
}
|
|
|
|
len = answer->nlmsg_len;
|
|
len -= NLMSG_LENGTH(sizeof(*ifi));
|
|
if (len < 0)
|
|
goto get_failed;
|
|
|
|
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
|
|
|
|
if (!tb[IFLA_LINKINFO])
|
|
goto get_failed;
|
|
|
|
parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
|
|
|
|
if (!linkinfo[IFLA_INFO_DATA])
|
|
goto get_failed;
|
|
|
|
parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX,
|
|
linkinfo[IFLA_INFO_DATA]);
|
|
|
|
rta = vtiinfo[IFLA_VTI_LOCAL];
|
|
if (rta && get_addr_rta(&saddr, rta, AF_INET6))
|
|
goto get_failed;
|
|
|
|
rta = vtiinfo[IFLA_VTI_REMOTE];
|
|
if (rta && get_addr_rta(&daddr, rta, AF_INET6))
|
|
goto get_failed;
|
|
|
|
if (vtiinfo[IFLA_VTI_IKEY])
|
|
ikey = rta_getattr_u32(vtiinfo[IFLA_VTI_IKEY]);
|
|
|
|
if (vtiinfo[IFLA_VTI_OKEY])
|
|
okey = rta_getattr_u32(vtiinfo[IFLA_VTI_OKEY]);
|
|
|
|
if (vtiinfo[IFLA_VTI_LINK])
|
|
link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]);
|
|
|
|
if (vtiinfo[IFLA_VTI_FWMARK])
|
|
fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]);
|
|
|
|
free(answer);
|
|
}
|
|
|
|
while (argc > 0) {
|
|
if (!matches(*argv, "key")) {
|
|
NEXT_ARG();
|
|
ikey = okey = tnl_parse_key("key", *argv);
|
|
} else if (!matches(*argv, "ikey")) {
|
|
NEXT_ARG();
|
|
ikey = tnl_parse_key("ikey", *argv);
|
|
} else if (!matches(*argv, "okey")) {
|
|
NEXT_ARG();
|
|
okey = tnl_parse_key("okey", *argv);
|
|
} else if (!matches(*argv, "remote")) {
|
|
NEXT_ARG();
|
|
get_addr(&daddr, *argv, AF_INET6);
|
|
} else if (!matches(*argv, "local")) {
|
|
NEXT_ARG();
|
|
get_addr(&saddr, *argv, AF_INET6);
|
|
} else if (!matches(*argv, "dev")) {
|
|
NEXT_ARG();
|
|
link = ll_name_to_index(*argv);
|
|
if (!link)
|
|
exit(nodev(*argv));
|
|
} else if (strcmp(*argv, "fwmark") == 0) {
|
|
NEXT_ARG();
|
|
if (get_u32(&fwmark, *argv, 0))
|
|
invarg("invalid fwmark\n", *argv);
|
|
} else {
|
|
vti6_print_help(lu, argc, argv, stderr);
|
|
return -1;
|
|
}
|
|
argc--; argv++;
|
|
}
|
|
|
|
addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
|
|
addattr32(n, 1024, IFLA_VTI_OKEY, okey);
|
|
if (is_addrtype_inet_not_unspec(&saddr))
|
|
addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
|
|
if (is_addrtype_inet_not_unspec(&daddr))
|
|
addattr_l(n, 1024, IFLA_VTI_REMOTE, daddr.data, daddr.bytelen);
|
|
addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
|
|
if (link)
|
|
addattr32(n, 1024, IFLA_VTI_LINK, link);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|
{
|
|
char s2[64];
|
|
|
|
if (!tb)
|
|
return;
|
|
|
|
tnl_print_endpoint("remote", tb[IFLA_VTI_REMOTE], AF_INET6);
|
|
tnl_print_endpoint("local", tb[IFLA_VTI_LOCAL], AF_INET6);
|
|
|
|
if (tb[IFLA_VTI_LINK]) {
|
|
__u32 link = rta_getattr_u32(tb[IFLA_VTI_LINK]);
|
|
|
|
if (link) {
|
|
print_string(PRINT_ANY, "link", "dev %s ",
|
|
ll_index_to_name(link));
|
|
}
|
|
}
|
|
|
|
if (tb[IFLA_VTI_IKEY]) {
|
|
struct rtattr *rta = tb[IFLA_VTI_IKEY];
|
|
__u32 key = rta_getattr_u32(rta);
|
|
|
|
if (key && inet_ntop(AF_INET, RTA_DATA(rta), s2, sizeof(s2)))
|
|
print_string(PRINT_ANY, "ikey", "ikey %s ", s2);
|
|
}
|
|
|
|
if (tb[IFLA_VTI_OKEY]) {
|
|
struct rtattr *rta = tb[IFLA_VTI_OKEY];
|
|
__u32 key = rta_getattr_u32(rta);
|
|
|
|
if (key && inet_ntop(AF_INET, RTA_DATA(rta), s2, sizeof(s2)))
|
|
print_string(PRINT_ANY, "okey", "okey %s ", s2);
|
|
}
|
|
|
|
if (tb[IFLA_VTI_FWMARK]) {
|
|
__u32 fwmark = rta_getattr_u32(tb[IFLA_VTI_FWMARK]);
|
|
|
|
if (fwmark) {
|
|
print_0xhex(PRINT_ANY,
|
|
"fwmark", "fwmark %#llx ", fwmark);
|
|
}
|
|
}
|
|
}
|
|
|
|
struct link_util vti6_link_util = {
|
|
.id = "vti6",
|
|
.maxattr = IFLA_VTI_MAX,
|
|
.parse_opt = vti6_parse_opt,
|
|
.print_opt = vti6_print_opt,
|
|
.print_help = vti6_print_help,
|
|
};
|