Commit 6ad355ca authored by Stephen Hemminger's avatar Stephen Hemminger

Merge branch 'master' into net-next

parents 0b7e3fc8 654ae881
...@@ -354,7 +354,7 @@ static int do_tunnels_list(struct ip6_tnl_parm2 *p) ...@@ -354,7 +354,7 @@ static int do_tunnels_list(struct ip6_tnl_parm2 *p)
fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n"); fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n");
goto end; goto end;
} }
if (sscanf(ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld", if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu",
&rx_bytes, &rx_packets, &rx_errs, &rx_drops, &rx_bytes, &rx_packets, &rx_errs, &rx_drops,
&rx_fifo, &rx_frame, &rx_multi, &rx_fifo, &rx_frame, &rx_multi,
&tx_bytes, &tx_packets, &tx_errs, &tx_drops, &tx_bytes, &tx_packets, &tx_errs, &tx_drops,
......
...@@ -28,12 +28,6 @@ static void explain(void) ...@@ -28,12 +28,6 @@ static void explain(void)
vrf_explain(stderr); vrf_explain(stderr);
} }
static int table_arg(void)
{
fprintf(stderr,"Error: argument of \"table\" must be 0-32767 and currently unused\n");
return -1;
}
static int vrf_parse_opt(struct link_util *lu, int argc, char **argv, static int vrf_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n) struct nlmsghdr *n)
{ {
...@@ -43,9 +37,8 @@ static int vrf_parse_opt(struct link_util *lu, int argc, char **argv, ...@@ -43,9 +37,8 @@ static int vrf_parse_opt(struct link_util *lu, int argc, char **argv,
NEXT_ARG(); NEXT_ARG();
table = atoi(*argv); if (rtnl_rttable_a2n(&table, *argv))
if (table > 32767) invarg("invalid table ID\n", *argv);
return table_arg();
addattr32(n, 1024, IFLA_VRF_TABLE, table); addattr32(n, 1024, IFLA_VRF_TABLE, table);
} else if (matches(*argv, "help") == 0) { } else if (matches(*argv, "help") == 0) {
explain(); explain();
......
...@@ -577,24 +577,23 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -577,24 +577,23 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (mxrta[i] == NULL) if (mxrta[i] == NULL)
continue; continue;
if (i < sizeof(mx_names)/sizeof(char*) && mx_names[i])
fprintf(fp, " %s", mx_names[i]);
else
fprintf(fp, " metric %d", i);
if (mxlock & (1<<i)) if (mxlock & (1<<i))
fprintf(fp, " lock"); fprintf(fp, " lock");
if (i != RTAX_CC_ALGO) if (i != RTAX_CC_ALGO)
val = rta_getattr_u32(mxrta[i]); val = rta_getattr_u32(mxrta[i]);
if (i == RTAX_HOPLIMIT && (int)val == -1)
continue;
if (i < sizeof(mx_names)/sizeof(char*) && mx_names[i])
fprintf(fp, " %s", mx_names[i]);
else
fprintf(fp, " metric %d", i);
switch (i) { switch (i) {
case RTAX_FEATURES: case RTAX_FEATURES:
print_rtax_features(fp, val); print_rtax_features(fp, val);
break; break;
case RTAX_HOPLIMIT:
if ((int)val == -1)
val = 0;
/* fall through */
default: default:
fprintf(fp, " %u", val); fprintf(fp, " %u", val);
break; break;
......
...@@ -50,7 +50,8 @@ static void usage(void) ...@@ -50,7 +50,8 @@ static void usage(void)
static void set_tunnel_proto(struct ip_tunnel_parm *p, int proto) static void set_tunnel_proto(struct ip_tunnel_parm *p, int proto)
{ {
if (p->iph.protocol && p->iph.protocol != proto) { if (p->iph.protocol && p->iph.protocol != proto) {
fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); fprintf(stderr,
"You managed to ask for more than one tunnel mode.\n");
exit(-1); exit(-1);
} }
p->iph.protocol = proto; p->iph.protocol = proto;
...@@ -91,7 +92,8 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) ...@@ -91,7 +92,8 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
set_tunnel_proto(p, IPPROTO_IPIP); set_tunnel_proto(p, IPPROTO_IPIP);
p->i_flags |= VTI_ISVTI; p->i_flags |= VTI_ISVTI;
} else { } else {
fprintf(stderr,"Unknown tunnel mode \"%s\"\n", *argv); fprintf(stderr,
"Unknown tunnel mode \"%s\"\n", *argv);
exit(-1); exit(-1);
} }
} else if (strcmp(*argv, "key") == 0) { } else if (strcmp(*argv, "key") == 0) {
...@@ -144,6 +146,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) ...@@ -144,6 +146,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
strcmp(*argv, "hoplimit") == 0 || strcmp(*argv, "hoplimit") == 0 ||
strcmp(*argv, "hlim") == 0) { strcmp(*argv, "hlim") == 0) {
__u8 uval; __u8 uval;
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "inherit") != 0) { if (strcmp(*argv, "inherit") != 0) {
if (get_u8(&uval, *argv, 0)) if (get_u8(&uval, *argv, 0))
...@@ -155,6 +158,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) ...@@ -155,6 +158,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
matches(*argv, "dsfield") == 0) { matches(*argv, "dsfield") == 0) {
char *dsfield; char *dsfield;
__u32 uval; __u32 uval;
NEXT_ARG(); NEXT_ARG();
dsfield = *argv; dsfield = *argv;
strsep(&dsfield, "/"); strsep(&dsfield, "/");
...@@ -169,15 +173,17 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) ...@@ -169,15 +173,17 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
p->iph.tos |= uval; p->iph.tos |= uval;
} }
} else { } else {
if (strcmp(*argv, "name") == 0) { if (strcmp(*argv, "name") == 0)
NEXT_ARG(); NEXT_ARG();
} else if (matches(*argv, "help") == 0) else if (matches(*argv, "help") == 0)
usage(); usage();
if (p->name[0]) if (p->name[0])
duparg2("name", *argv); duparg2("name", *argv);
strncpy(p->name, *argv, IFNAMSIZ - 1); strncpy(p->name, *argv, IFNAMSIZ - 1);
if (cmd == SIOCCHGTUNNEL && count == 0) { if (cmd == SIOCCHGTUNNEL && count == 0) {
struct ip_tunnel_parm old_p; struct ip_tunnel_parm old_p;
memset(&old_p, 0, sizeof(old_p)); memset(&old_p, 0, sizeof(old_p));
if (tnl_get_ioctl(*argv, &old_p)) if (tnl_get_ioctl(*argv, &old_p))
return -1; return -1;
...@@ -268,8 +274,10 @@ static int do_add(int cmd, int argc, char **argv) ...@@ -268,8 +274,10 @@ static int do_add(int cmd, int argc, char **argv)
return -1; return -1;
} }
if (!(basedev = tnl_defname(&p))) { basedev = tnl_defname(&p);
fprintf(stderr, "cannot determine tunnel mode (ipip, gre, vti or sit)\n"); if (!basedev) {
fprintf(stderr,
"cannot determine tunnel mode (ipip, gre, vti or sit)\n");
return -1; return -1;
} }
...@@ -312,18 +320,18 @@ static void print_tunnel(struct ip_tunnel_parm *p) ...@@ -312,18 +320,18 @@ static void print_tunnel(struct ip_tunnel_parm *p)
prl[0].addr = htonl(INADDR_ANY); prl[0].addr = htonl(INADDR_ANY);
if (!tnl_prl_ioctl(SIOCGETPRL, p->name, prl)) if (!tnl_prl_ioctl(SIOCGETPRL, p->name, prl))
for (i = 1; i < sizeof(prl) / sizeof(prl[0]); i++) for (i = 1; i < ARRAY_SIZE(prl); i++) {
{ if (prl[i].addr != htonl(INADDR_ANY)) {
if (prl[i].addr != htonl(INADDR_ANY)) { printf(" %s %s ",
printf(" %s %s ", (prl[i].flags & PRL_DEFAULT) ? "pdr" : "pr",
(prl[i].flags & PRL_DEFAULT) ? "pdr" : "pr", format_host(AF_INET, 4, &prl[i].addr, s1, sizeof(s1)));
format_host(AF_INET, 4, &prl[i].addr, s1, sizeof(s1))); }
} }
}
} }
if (p->link) { if (p->link) {
const char *n = ll_index_to_name(p->link); const char *n = ll_index_to_name(p->link);
if (n) if (n)
printf(" dev %s", n); printf(" dev %s", n);
} }
...@@ -381,6 +389,7 @@ static int do_tunnels_list(struct ip_tunnel_parm *p) ...@@ -381,6 +389,7 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
char buf[512]; char buf[512];
int err = -1; int err = -1;
FILE *fp = fopen("/proc/net/dev", "r"); FILE *fp = fopen("/proc/net/dev", "r");
if (fp == NULL) { if (fp == NULL) {
perror("fopen"); perror("fopen");
return -1; return -1;
...@@ -404,12 +413,13 @@ static int do_tunnels_list(struct ip_tunnel_parm *p) ...@@ -404,12 +413,13 @@ static int do_tunnels_list(struct ip_tunnel_parm *p)
char *ptr; char *ptr;
buf[sizeof(buf) - 1] = 0; buf[sizeof(buf) - 1] = 0;
if ((ptr = strchr(buf, ':')) == NULL || ptr = strchr(buf, ':');
if (ptr == NULL ||
(*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n"); fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n");
goto end; goto end;
} }
if (sscanf(ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld", if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu",
&rx_bytes, &rx_packets, &rx_errs, &rx_drops, &rx_bytes, &rx_packets, &rx_errs, &rx_drops,
&rx_fifo, &rx_frame, &rx_multi, &rx_fifo, &rx_frame, &rx_multi,
&tx_bytes, &tx_packets, &tx_errs, &tx_drops, &tx_bytes, &tx_packets, &tx_errs, &tx_drops,
...@@ -463,7 +473,8 @@ static int do_show(int argc, char **argv) ...@@ -463,7 +473,8 @@ static int do_show(int argc, char **argv)
if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0) if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0)
return -1; return -1;
if (!(basedev = tnl_defname(&p))) basedev = tnl_defname(&p);
if (!basedev)
return do_tunnels_list(&p); return do_tunnels_list(&p);
if (tnl_get_ioctl(p.name[0] ? p.name : basedev, &p)) if (tnl_get_ioctl(p.name[0] ? p.name : basedev, &p))
...@@ -507,11 +518,13 @@ static int do_prl(int argc, char **argv) ...@@ -507,11 +518,13 @@ static int do_prl(int argc, char **argv)
strncpy(medium, *argv, IFNAMSIZ-1); strncpy(medium, *argv, IFNAMSIZ-1);
devname++; devname++;
} else { } else {
fprintf(stderr,"Invalid PRL parameter \"%s\"\n", *argv); fprintf(stderr,
"Invalid PRL parameter \"%s\"\n", *argv);
exit(-1); exit(-1);
} }
if (count > 1) { if (count > 1) {
fprintf(stderr,"One PRL entry at a time\n"); fprintf(stderr,
"One PRL entry at a time\n");
exit(-1); exit(-1);
} }
argc--; argv++; argc--; argv++;
...@@ -557,7 +570,8 @@ static int do_6rd(int argc, char **argv) ...@@ -557,7 +570,8 @@ static int do_6rd(int argc, char **argv)
strncpy(medium, *argv, IFNAMSIZ-1); strncpy(medium, *argv, IFNAMSIZ-1);
devname++; devname++;
} else { } else {
fprintf(stderr,"Invalid 6RD parameter \"%s\"\n", *argv); fprintf(stderr,
"Invalid 6RD parameter \"%s\"\n", *argv);
exit(-1); exit(-1);
} }
argc--; argv++; argc--; argv++;
...@@ -570,8 +584,35 @@ static int do_6rd(int argc, char **argv) ...@@ -570,8 +584,35 @@ static int do_6rd(int argc, char **argv)
return tnl_6rd_ioctl(cmd, medium, &ip6rd); return tnl_6rd_ioctl(cmd, medium, &ip6rd);
} }
static int tunnel_mode_is_ipv6(char *tunnel_mode)
{
static const char * const ipv6_modes[] = {
"ipv6/ipv6", "ip6ip6",
"vti6",
"ip/ipv6", "ipv4/ipv6", "ipip6", "ip4ip6",
"ip6gre", "gre/ipv6",
"any/ipv6", "any"
};
int i;
for (i = 0; i < ARRAY_SIZE(ipv6_modes); i++) {
if (strcmp(ipv6_modes[i], tunnel_mode) == 0)
return 1;
}
return 0;
}
int do_iptunnel(int argc, char **argv) int do_iptunnel(int argc, char **argv)
{ {
int i;
for (i = 0; i < argc - 1; i++) {
if (strcmp(argv[i], "mode") == 0) {
if (tunnel_mode_is_ipv6(argv[i + 1]))
preferred_family = AF_INET6;
break;
}
}
switch (preferred_family) { switch (preferred_family) {
case AF_UNSPEC: case AF_UNSPEC:
preferred_family = AF_INET; preferred_family = AF_INET;
......
...@@ -332,7 +332,7 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth, ...@@ -332,7 +332,7 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth,
} }
int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
struct nlmsghdr *answer, size_t len) struct nlmsghdr *answer, size_t maxlen)
{ {
int status; int status;
unsigned seq; unsigned seq;
...@@ -415,7 +415,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, ...@@ -415,7 +415,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
} else if (!err->error) { } else if (!err->error) {
if (answer) if (answer)
memcpy(answer, h, memcpy(answer, h,
MIN(len, h->nlmsg_len)); MIN(maxlen, h->nlmsg_len));
return 0; return 0;
} }
...@@ -427,7 +427,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, ...@@ -427,7 +427,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
if (answer) { if (answer) {
memcpy(answer, h, memcpy(answer, h,
MIN(len, h->nlmsg_len)); MIN(maxlen, h->nlmsg_len));
return 0; return 0;
} }
......
...@@ -181,7 +181,7 @@ Match Resource Reservation Protocol (RSVP) packets. ...@@ -181,7 +181,7 @@ Match Resource Reservation Protocol (RSVP) packets.
.TP .TP
tcindex tcindex
Filter packets based on traffic control index. See Filter packets based on traffic control index. See
.BR tc-index (8). .BR tc-tcindex (8).
.TP .TP
u32 u32
Generic filtering on arbitrary packet data, assisted by syntax to abstract common operations. See Generic filtering on arbitrary packet data, assisted by syntax to abstract common operations. See
......
#!/bin/sh
source lib/generic.sh
TUNNEL_NAME="tunnel_test_ip"
ts_log "[Testing add/del tunnels]"
ts_ip "$0" "Add GRE tunnel over IPv4" tunnel add name $TUNNEL_NAME mode gre local 1.1.1.1 remote 2.2.2.2
ts_ip "$0" "Del GRE tunnel over IPv4" tunnel del $TUNNEL_NAME
ts_ip "$0" "Add GRE tunnel over IPv6" tunnel add name $TUNNEL_NAME mode ip6gre local dead:beef::1 remote dead:beef::2
ts_ip "$0" "Del GRE tunnel over IPv6" tunnel del $TUNNEL_NAME
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment