From b0ef5945af9d68a435868546b4bf30020a6e6ab8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phan=20Kochen?= Date: Sun, 17 Jun 2012 17:26:35 +0200 Subject: [PATCH] Add 6rd options to tunnel spec. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch adds support for setting the 6rd tunnel options. These are the same options normally specified with `ip tunnel 6rd ...`. Signed-off-by: Stéphan Kochen --- system-linux.c | 40 ++++++++++++++++++++++++++++++++++------ system.c | 2 ++ system.h | 2 ++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/system-linux.c b/system-linux.c index ceb5ac5..aaa8230 100644 --- a/system-linux.c +++ b/system-linux.c @@ -1026,7 +1026,7 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr) struct blob_attr *cur; struct ip_tunnel_parm p; const char *base, *str; - int cmd = SIOCADDTUNNEL; + bool is_sit; system_del_ip_tunnel(name); @@ -1035,12 +1035,12 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr) blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb, blob_data(attr), blob_len(attr)); - cur = tb[TUNNEL_ATTR_TYPE]; - if (!cur) + if (!(cur = tb[TUNNEL_ATTR_TYPE])) return -EINVAL; - str = blobmsg_data(cur); - if (!strcmp(str, "sit")) { + is_sit = !strcmp(str, "sit"); + + if (is_sit) { p.iph.protocol = IPPROTO_IPV6; base = "sit0"; } else @@ -1062,5 +1062,33 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr) } strncpy(p.name, name, sizeof(p.name)); - return tunnel_ioctl(base, cmd, &p); + if (tunnel_ioctl(base, SIOCADDTUNNEL, &p) < 0) + return -1; + + cur = tb[TUNNEL_ATTR_6RD_PREFIX]; + if (cur && is_sit) { + unsigned int mask; + struct ip_tunnel_6rd p6; + + memset(&p6, 0, sizeof(p6)); + + if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur), + &p6.prefix, &mask) || mask > 128) + return -EINVAL; + p6.prefixlen = mask; + + if ((cur = tb[TUNNEL_ATTR_6RD_RELAY_PREFIX])) { + if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur), + &p6.relay_prefix, &mask) || mask > 32) + return -EINVAL; + p6.relay_prefixlen = mask; + } + + if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) { + system_del_ip_tunnel(name); + return -1; + } + } + + return 0; } diff --git a/system.c b/system.c index c85d0e4..1096ad2 100644 --- a/system.c +++ b/system.c @@ -19,6 +19,8 @@ static const struct blobmsg_policy tunnel_attrs[__TUNNEL_ATTR_MAX] = { [TUNNEL_ATTR_LOCAL] = { "local", BLOBMSG_TYPE_STRING }, [TUNNEL_ATTR_REMOTE] = { "remote", BLOBMSG_TYPE_STRING }, [TUNNEL_ATTR_TTL] = { "ttl", BLOBMSG_TYPE_INT32 }, + [TUNNEL_ATTR_6RD_PREFIX] = { "6rd-prefix", BLOBMSG_TYPE_STRING }, + [TUNNEL_ATTR_6RD_RELAY_PREFIX] = { "6rd-relay-prefix", BLOBMSG_TYPE_STRING }, }; const struct config_param_list tunnel_attr_list = { diff --git a/system.h b/system.h index 73ceb41..5e275ca 100644 --- a/system.h +++ b/system.h @@ -24,6 +24,8 @@ enum tunnel_param { TUNNEL_ATTR_REMOTE, TUNNEL_ATTR_LOCAL, TUNNEL_ATTR_TTL, + TUNNEL_ATTR_6RD_PREFIX, + TUNNEL_ATTR_6RD_RELAY_PREFIX, __TUNNEL_ATTR_MAX }; -- 2.11.0