IPv6: 6rd iproute2 support
This patch provides iproute2 facilities to configure 6rd tunnel. To configure a 6rd tunnel, you need to configure a sit tunnel and set 6rd prefix as following : ip tunnel add sit1 mode sit local a.b.c.d ttl 64 ip tunnel 6rd dev sit1 6rd-prefix xxxx:yyyy::/z Optionally you can provide a relay prefix : ip tunnel 6rd dev sit1 6rd-relay_prefix e.f.g.h/i Finally you can reset previous tunnel settings : ip tunnel 6rd dev sit1 6rd-reset Signed-off-by: Alexandre Cassen <acassen@freebox.fr>
This commit is contained in:
parent
a1b9ffccc2
commit
b88215c468
|
|
@ -32,10 +32,11 @@ static void usage(void) __attribute__((noreturn));
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl } [ NAME ]\n");
|
fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]\n");
|
||||||
fprintf(stderr, " [ mode { ipip | gre | sit | isatap } ] [ remote ADDR ] [ local ADDR ]\n");
|
fprintf(stderr, " [ mode { ipip | gre | sit | isatap } ] [ remote ADDR ] [ local ADDR ]\n");
|
||||||
fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\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, " [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n");
|
||||||
|
fprintf(stderr, " [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n");
|
||||||
fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
|
fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Where: NAME := STRING\n");
|
fprintf(stderr, "Where: NAME := STRING\n");
|
||||||
|
|
@ -302,11 +303,13 @@ static int do_del(int argc, char **argv)
|
||||||
|
|
||||||
static void print_tunnel(struct ip_tunnel_parm *p)
|
static void print_tunnel(struct ip_tunnel_parm *p)
|
||||||
{
|
{
|
||||||
|
struct ip_tunnel_6rd ip6rd;
|
||||||
char s1[1024];
|
char s1[1024];
|
||||||
char s2[1024];
|
char s2[1024];
|
||||||
char s3[64];
|
char s3[64];
|
||||||
char s4[64];
|
char s4[64];
|
||||||
|
|
||||||
|
memset(&ip6rd, 0, sizeof(ip6rd));
|
||||||
inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
|
inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
|
||||||
inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
|
inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
|
||||||
|
|
||||||
|
|
@ -362,6 +365,17 @@ static void print_tunnel(struct ip_tunnel_parm *p)
|
||||||
if (!(p->iph.frag_off&htons(IP_DF)))
|
if (!(p->iph.frag_off&htons(IP_DF)))
|
||||||
printf(" nopmtudisc");
|
printf(" nopmtudisc");
|
||||||
|
|
||||||
|
if (!tnl_ioctl_get_6rd(p->name, &ip6rd) && ip6rd.prefixlen) {
|
||||||
|
printf(" 6rd-prefix %s/%u ",
|
||||||
|
inet_ntop(AF_INET6, &ip6rd.prefix, s1, sizeof(s1)),
|
||||||
|
ip6rd.prefixlen);
|
||||||
|
if (ip6rd.relay_prefix) {
|
||||||
|
printf("6rd-relay_prefix %s/%u ",
|
||||||
|
format_host(AF_INET, 4, &ip6rd.relay_prefix, s1, sizeof(s1)),
|
||||||
|
ip6rd.relay_prefixlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key)
|
if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key)
|
||||||
printf(" key %s", s3);
|
printf(" key %s", s3);
|
||||||
else if ((p->i_flags|p->o_flags)&GRE_KEY) {
|
else if ((p->i_flags|p->o_flags)&GRE_KEY) {
|
||||||
|
|
@ -528,6 +542,52 @@ static int do_prl(int argc, char **argv)
|
||||||
return tnl_prl_ioctl(cmd, medium, &p);
|
return tnl_prl_ioctl(cmd, medium, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_6rd(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct ip_tunnel_6rd ip6rd;
|
||||||
|
int devname = 0;
|
||||||
|
int cmd = 0;
|
||||||
|
char medium[IFNAMSIZ];
|
||||||
|
inet_prefix prefix;
|
||||||
|
|
||||||
|
memset(&ip6rd, 0, sizeof(ip6rd));
|
||||||
|
memset(&medium, 0, sizeof(medium));
|
||||||
|
|
||||||
|
while (argc > 0) {
|
||||||
|
if (strcmp(*argv, "6rd-prefix") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (get_prefix(&prefix, *argv, AF_INET6))
|
||||||
|
invarg("invalid 6rd_prefix\n", *argv);
|
||||||
|
cmd = SIOCADD6RD;
|
||||||
|
memcpy(&ip6rd.prefix, prefix.data, 16);
|
||||||
|
ip6rd.prefixlen = prefix.bitlen;
|
||||||
|
} else if (strcmp(*argv, "6rd-relay_prefix") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (get_prefix(&prefix, *argv, AF_INET))
|
||||||
|
invarg("invalid 6rd-relay_prefix\n", *argv);
|
||||||
|
cmd = SIOCADD6RD;
|
||||||
|
memcpy(&ip6rd.relay_prefix, prefix.data, 4);
|
||||||
|
ip6rd.relay_prefixlen = prefix.bitlen;
|
||||||
|
} else if (strcmp(*argv, "6rd-reset") == 0) {
|
||||||
|
cmd = SIOCDEL6RD;
|
||||||
|
} else if (strcmp(*argv, "dev") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
strncpy(medium, *argv, IFNAMSIZ-1);
|
||||||
|
devname++;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"%s: Invalid 6RD parameter.\n", *argv);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
|
if (devname == 0) {
|
||||||
|
fprintf(stderr, "Must specify dev.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tnl_6rd_ioctl(cmd, medium, &ip6rd);
|
||||||
|
}
|
||||||
|
|
||||||
int do_iptunnel(int argc, char **argv)
|
int do_iptunnel(int argc, char **argv)
|
||||||
{
|
{
|
||||||
switch (preferred_family) {
|
switch (preferred_family) {
|
||||||
|
|
@ -561,6 +621,8 @@ int do_iptunnel(int argc, char **argv)
|
||||||
return do_show(argc-1, argv+1);
|
return do_show(argc-1, argv+1);
|
||||||
if (matches(*argv, "prl") == 0)
|
if (matches(*argv, "prl") == 0)
|
||||||
return do_prl(argc-1, argv+1);
|
return do_prl(argc-1, argv+1);
|
||||||
|
if (matches(*argv, "6rd") == 0)
|
||||||
|
return do_6rd(argc-1, argv+1);
|
||||||
if (matches(*argv, "help") == 0)
|
if (matches(*argv, "help") == 0)
|
||||||
usage();
|
usage();
|
||||||
} else
|
} else
|
||||||
|
|
|
||||||
17
ip/tunnel.c
17
ip/tunnel.c
|
|
@ -168,7 +168,7 @@ int tnl_del_ioctl(const char *basedev, const char *name, void *p)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tnl_prl_ioctl(int cmd, const char *name, void *p)
|
static int tnl_gen_ioctl(int cmd, const char *name, void *p)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
@ -183,3 +183,18 @@ int tnl_prl_ioctl(int cmd, const char *name, void *p)
|
||||||
close(fd);
|
close(fd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tnl_prl_ioctl(int cmd, const char *name, void *p)
|
||||||
|
{
|
||||||
|
return tnl_gen_ioctl(cmd, name, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tnl_6rd_ioctl(int cmd, const char *name, void *p)
|
||||||
|
{
|
||||||
|
return tnl_gen_ioctl(cmd, name, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tnl_ioctl_get_6rd(const char *name, void *p)
|
||||||
|
{
|
||||||
|
return tnl_gen_ioctl(SIOCGET6RD, name, p);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,7 @@ 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_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_del_ioctl(const char *basedev, const char *name, void *p);
|
||||||
int tnl_prl_ioctl(int cmd, const char *name, void *p);
|
int tnl_prl_ioctl(int cmd, const char *name, void *p);
|
||||||
|
int tnl_6rd_ioctl(int cmd, const char *name, void *p);
|
||||||
|
int tnl_ioctl_get_6rd(const char *name, void *p);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue