* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/*
- * based on:
- * $Id: s.ipv6tunnel.c 1.7 02/12/11 11:21:51+02:00 antti@traci.mipl.mediapoli.com $
- *
- */
/*
* Author:
* Masahide NAKAMURA @USAGI
#include "utils.h"
#include "tunnel.h"
+#include "ip_common.h"
#define IP6_FLOWINFO_TCLASS htonl(0x0FF00000)
#define IP6_FLOWINFO_FLOWLABEL htonl(0x000FFFFF)
IPV6_DEFAULT_TNL_ENCAP_LIMIT);
fprintf(stderr, " TTL := 0..255 (default=%d)\n",
DEFAULT_TNL_HOP_LIMIT);
- fprintf(stderr, " TOS := { 0x0..0xff | inherit }\n");
+ fprintf(stderr, " TCLASS := { 0x0..0xff | inherit }\n");
fprintf(stderr, " FLOWLABEL := { 0x0..0xfffff | inherit }\n");
exit(-1);
}
printf("%s: %s/ipv6 remote %s local %s",
p->name, tnl_strproto(p->proto), remote, local);
if (p->link) {
- char *n = tnl_ioctl_get_ifname(p->link);
+ const char *n = ll_index_to_name(p->link);
if (n)
printf(" dev %s", n);
}
printf(" dscp inherit");
}
-static int parse_args(int argc, char **argv, struct ip6_tnl_parm *p)
+static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm *p)
{
+ int count = 0;
char medium[IFNAMSIZ];
memset(medium, 0, sizeof(medium));
strcmp(*argv, "any") == 0)
p->proto = 0;
else {
- fprintf(stderr,"Cannot guess tunnel mode.\n");
+ fprintf(stderr,"Unknown tunnel mode \"%s\"\n", *argv);
exit(-1);
}
} else if (strcmp(*argv, "remote") == 0) {
if (get_u8(&uval, *argv, 0) < -1)
invarg("invalid ELIM", *argv);
p->encap_limit = uval;
+ p->flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
}
} else if (strcmp(*argv, "hoplimit") == 0 ||
strcmp(*argv, "ttl") == 0 ||
matches(*argv, "dsfield") == 0) {
__u8 uval;
NEXT_ARG();
+ p->flowinfo &= ~IP6_FLOWINFO_TCLASS;
if (strcmp(*argv, "inherit") == 0)
p->flags |= IP6_TNL_F_USE_ORIG_TCLASS;
else {
strcmp(*argv, "fl") == 0) {
__u32 uval;
NEXT_ARG();
+ p->flowinfo &= ~IP6_FLOWINFO_FLOWLABEL;
if (strcmp(*argv, "inherit") == 0)
p->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
else {
if (p->name[0])
duparg2("name", *argv);
strncpy(p->name, *argv, IFNAMSIZ - 1);
+ if (cmd == SIOCCHGTUNNEL && count == 0) {
+ struct ip6_tnl_parm old_p;
+ memset(&old_p, 0, sizeof(old_p));
+ if (tnl_get_ioctl(*argv, &old_p))
+ return -1;
+ *p = old_p;
+ }
}
+ count++;
argc--; argv++;
}
if (medium[0]) {
- p->link = tnl_ioctl_get_ifindex(medium);
+ p->link = ll_name_to_index(medium);
if (p->link == 0)
return -1;
}
}
/* skip two lines at the begenning of the file */
- fgets(buf, sizeof(buf), fp);
- fgets(buf, sizeof(buf), fp);
+ if (!fgets(buf, sizeof(buf), fp) ||
+ !fgets(buf, sizeof(buf), fp)) {
+ fprintf(stderr, "/proc/net/dev read error\n");
+ return -1;
+ }
while (fgets(buf, sizeof(buf), fp) != NULL) {
char name[IFNAMSIZ];
- int type;
+ int index, type;
unsigned long rx_bytes, rx_packets, rx_errs, rx_drops,
rx_fifo, rx_frame,
tx_bytes, tx_packets, tx_errs, tx_drops,
buf[sizeof(buf) - 1] = '\0';
if ((ptr = strchr(buf, ':')) == NULL ||
(*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
- fprintf(stderr, "Wrong format of /proc/net/dev. Sorry.\n");
+ fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n");
goto end;
}
if (sscanf(ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld",
continue;
if (p->name[0] && strcmp(p->name, name))
continue;
- type = tnl_ioctl_get_iftype(name);
+ index = ll_name_to_index(name);
+ if (index == 0)
+ continue;
+ type = ll_index_to_type(index);
if (type == -1) {
- fprintf(stderr, "Failed to get type of [%s]\n", name);
+ fprintf(stderr, "Failed to get type of \"%s\"\n", name);
continue;
}
if (type != ARPHRD_TUNNEL6)
memset(&p1, 0, sizeof(p1));
ip6_tnl_parm_init(&p1, 0);
strcpy(p1.name, name);
- p1.link = tnl_ioctl_get_ifindex(p1.name);
+ p1.link = ll_name_to_index(p1.name);
if (p1.link == 0)
continue;
if (tnl_get_ioctl(p1.name, &p1))
{
struct ip6_tnl_parm p;
+ ll_init_map(&rth);
ip6_tnl_parm_init(&p, 0);
+ p.proto = 0; /* default to any */
- if (parse_args(argc, argv, &p) < 0)
+ if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0)
return -1;
if (!p.name[0] || show_stats)
ip6_tnl_parm_init(&p, 1);
- if (parse_args(argc, argv, &p) < 0)
+ if (parse_args(argc, argv, cmd, &p) < 0)
return -1;
return tnl_add_ioctl(cmd,
ip6_tnl_parm_init(&p, 1);
- if (parse_args(argc, argv, &p) < 0)
+ if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0)
return -1;
return tnl_del_ioctl(p.name[0] ? p.name : "ip6tnl0", p.name, &p);
case AF_INET6:
break;
default:
- fprintf(stderr, "Unsupported family:%d\n", preferred_family);
+ fprintf(stderr, "Unsupported protocol family: %d\n", preferred_family);
exit(-1);
}
return do_add(SIOCADDTUNNEL, argc - 1, argv + 1);
if (matches(*argv, "change") == 0)
return do_add(SIOCCHGTUNNEL, argc - 1, argv + 1);
- if (matches(*argv, "del") == 0)
+ if (matches(*argv, "delete") == 0)
return do_del(argc - 1, argv + 1);
if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 ||