--- iproute/ip/iptunnel.c.orig 2008-05-06 11:52:23.000000000 -0700 +++ iproute/ip/iptunnel.c 2008-05-12 15:14:17.000000000 -0700 @@ -38,9 +38,11 @@ static void usage(void) __attribute__((n static void usage(void) { - fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n"); - fprintf(stderr, " [ mode { ipip | gre | sit | isatap } ] [ remote ADDR ] [ local ADDR ]\n"); + fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl } [ NAME ]\n"); + fprintf(stderr, " [ mode { ipip | gre | sit | isatap | vet } ]\n"); + fprintf(stderr, " [ remote ADDR ] [ local ADDR ]\n"); fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"); + fprintf(stderr, " [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n"); fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"); fprintf(stderr, "\n"); fprintf(stderr, "Where: NAME := STRING\n"); @@ -56,6 +58,7 @@ static int parse_args(int argc, char **a int count = 0; char medium[IFNAMSIZ]; int isatap = 0; + int vet = 0; memset(p, 0, sizeof(*p)); memset(&medium, 0, sizeof(medium)); @@ -98,6 +101,13 @@ static int parse_args(int argc, char **a } p->iph.protocol = IPPROTO_IPV6; isatap++; + } else if (strcmp(*argv, "vet") == 0) { + if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { + fprintf(stderr, "You managed to ask for more than one tunnel mode.\n"); + exit(-1); + } + p->iph.protocol = IPPROTO_IPV6; + vet++; } else { fprintf(stderr,"Cannot guess tunnel mode.\n"); exit(-1); @@ -223,6 +233,9 @@ static int parse_args(int argc, char **a else if (memcmp(p->name, "isatap", 6) == 0) { p->iph.protocol = IPPROTO_IPV6; isatap++; + } else if (memcmp(p->name, "vet", 3) == 0) { + p->iph.protocol = IPPROTO_IPV6; + vet++; } } @@ -258,6 +271,17 @@ static int parse_args(int argc, char **a } p->i_flags |= SIT_ISATAP; } + if (vet) { + if (p->iph.daddr) { + fprintf(stderr, "no remote with vet.\n"); + return -1; + } + if (p->link == 0) { + fprintf(stderr, "must specify dev (name of underlying IPv4 link).\n"); + return -1; + } + p->i_flags |= SIT_VET; + } return 0; } @@ -309,6 +333,56 @@ static int do_del(int argc, char **argv) return -1; } +static int do_prl(int argc, char **argv) +{ + struct ip_tunnel_prl p; + int count = 0; + int devname = 0; + int cmd = 0; + char medium[IFNAMSIZ]; + + memset(&p, 0, sizeof(p)); + memset(&medium, 0, sizeof(medium)); + + while (argc > 0) { + if (strcmp(*argv, "prl-default") == 0) { + NEXT_ARG(); + cmd = SIOCADDPRL; + p.addr = get_addr32(*argv); + p.flags |= PRL_DEFAULT; + count++; + } else if (strcmp(*argv, "prl-nodefault") == 0) { + NEXT_ARG(); + cmd = SIOCADDPRL; + p.addr = get_addr32(*argv); + count++; + } else if (strcmp(*argv, "prl-delete") == 0) { + NEXT_ARG(); + cmd = SIOCDELPRL; + p.addr = get_addr32(*argv); + count++; + } else if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + strncpy(medium, *argv, IFNAMSIZ-1); + devname++; + } else { + fprintf(stderr,"%s: Invalid PRL parameter.\n", *argv); + exit(-1); + } + if (count > 1) { + fprintf(stderr,"One PRL entry at a time.\n"); + exit(-1); + } + argc--; argv++; + } + if (devname == 0) { + fprintf(stderr, "Must specify dev.\n"); + exit(-1); + } + + return tnl_prl_ioctl(cmd, medium, &p); +} + static void print_tunnel(struct ip_tunnel_parm *p) { char s1[1024]; @@ -499,6 +573,8 @@ int do_iptunnel(int argc, char **argv) matches(*argv, "lst") == 0 || matches(*argv, "list") == 0) return do_show(argc-1, argv+1); + if (matches(*argv, "prl") == 0) + return do_prl(argc-1, argv+1); if (matches(*argv, "help") == 0) usage(); } else --- iproute/ip/tunnel.c.orig 2008-05-06 11:52:23.000000000 -0700 +++ iproute/ip/tunnel.c 2008-05-06 11:52:23.000000000 -0700 @@ -167,3 +167,19 @@ int tnl_del_ioctl(const char *basedev, c close(fd); return err; } + +int tnl_prl_ioctl(int cmd, const char *name, void *p) +{ + struct ifreq ifr; + int fd; + int err; + + strncpy(ifr.ifr_name, name, IFNAMSIZ); + ifr.ifr_ifru.ifru_data = p; + fd = socket(preferred_family, SOCK_DGRAM, 0); + err = ioctl(fd, cmd, &ifr); + if (err) + perror("ioctl"); + close(fd); + return err; +} --- iproute/ip/tunnel.h.orig 2008-05-06 11:52:23.000000000 -0700 +++ iproute/ip/tunnel.h 2008-05-06 11:52:23.000000000 -0700 @@ -31,5 +31,6 @@ char * tnl_ioctl_get_ifname(int idx); int tnl_get_ioctl(const char *basedev, void *p); int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p); int tnl_del_ioctl(const char *basedev, const char *name, void *p); +int tnl_prl_ioctl(int cmd, const char *name, void *p); #endif