summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2017-05-19 12:05:55 +0200
committerHans Dedecker <dedeckeh@gmail.com>2017-05-22 17:36:53 +0200
commit7573880ac042c6e5c8d48b1ad83d357b5e02743b (patch)
tree4e8b6d62bcef165edea592b5439cd9a195110130
parenta063705a03a6c5a41b5f7aed251bfb3ba5c844c3 (diff)
system-linux: parse 6rd specific settings as nested json data object
Parse 6rd specific settings prefix, relay-prefix as nested json data objects. At the same time improve 6rd error handling. Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r--system-linux.c89
-rw-r--r--system.c12
-rw-r--r--system.h7
3 files changed, 76 insertions, 32 deletions
diff --git a/system-linux.c b/system-linux.c
index ddc31d8..0ac4ae6 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -81,6 +81,9 @@ static struct nl_sock *sock_rtnl = NULL;
static int cb_rtnl_event(struct nl_msg *msg, void *arg);
static void handle_hotplug_event(struct uloop_fd *u, unsigned int events);
+static int system_add_proto_tunnel(const char *name, const uint8_t proto,
+ const unsigned int link, struct blob_attr **tb);
+static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb);
static char dev_buf[256];
@@ -2705,6 +2708,59 @@ failure:
}
#endif
+static int system_add_sit_tunnel(const char *name, const unsigned int link, struct blob_attr **tb)
+{
+ struct blob_attr *cur;
+ int ret = 0;
+
+ if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
+ return -1;
+
+#ifdef SIOCADD6RD
+ if ((cur = tb[TUNNEL_ATTR_DATA])) {
+ struct blob_attr *tb_data[__SIXRD_DATA_ATTR_MAX];
+ unsigned int mask;
+ struct ip_tunnel_6rd p6;
+
+ blobmsg_parse(sixrd_data_attr_list.params, __SIXRD_DATA_ATTR_MAX, tb_data,
+ blobmsg_data(cur), blobmsg_len(cur));
+
+ memset(&p6, 0, sizeof(p6));
+
+ if ((cur = tb_data[SIXRD_DATA_PREFIX])) {
+ if (!parse_ip_and_netmask(AF_INET6, blobmsg_data(cur),
+ &p6.prefix, &mask) || mask > 128) {
+ ret = -EINVAL;
+ goto failure;
+ }
+
+ p6.prefixlen = mask;
+ }
+
+ if ((cur = tb[SIXRD_DATA_RELAY_PREFIX])) {
+ if (!parse_ip_and_netmask(AF_INET, blobmsg_data(cur),
+ &p6.relay_prefix, &mask) || mask > 32) {
+ ret = -EINVAL;
+ goto failure;
+ }
+
+ p6.relay_prefixlen = mask;
+ }
+
+ if (tunnel_ioctl(name, SIOCADD6RD, &p6) < 0) {
+ ret = -1;
+ goto failure;
+ }
+ }
+#endif
+
+ return ret;
+
+failure:
+ __system_del_ip_tunnel(name, tb);
+ return ret;
+}
+
static int system_add_proto_tunnel(const char *name, const uint8_t proto, const unsigned int link, struct blob_attr **tb)
{
struct blob_attr *cur;
@@ -2853,37 +2909,10 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
link = iface->l3_dev.dev->ifindex;
}
- if (!strcmp(str, "sit")) {
- if (system_add_proto_tunnel(name, IPPROTO_IPV6, link, tb) < 0)
- return -1;
-
-#ifdef SIOCADD6RD
- if ((cur = tb[TUNNEL_ATTR_6RD_PREFIX])) {
- 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, tb);
- return -1;
- }
- }
-#endif
+ if (!strcmp(str, "sit"))
+ return system_add_sit_tunnel(name, link, tb);
#ifdef IFLA_IPTUN_MAX
- } else if (!strcmp(str, "ipip6")) {
+ else if (!strcmp(str, "ipip6")) {
struct nl_msg *nlm = nlmsg_alloc_simple(RTM_NEWLINK,
NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE);
struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC };
diff --git a/system.c b/system.c
index 3d4a979..bf3fd77 100644
--- a/system.c
+++ b/system.c
@@ -23,8 +23,6 @@ static const struct blobmsg_policy tunnel_attrs[__TUNNEL_ATTR_MAX] = {
[TUNNEL_ATTR_DF] = { .name = "df", .type = BLOBMSG_TYPE_BOOL },
[TUNNEL_ATTR_TTL] = { .name = "ttl", .type = BLOBMSG_TYPE_INT32 },
[TUNNEL_ATTR_TOS] = { .name = "tos", .type = BLOBMSG_TYPE_STRING },
- [TUNNEL_ATTR_6RD_PREFIX] = {.name = "6rd-prefix", .type = BLOBMSG_TYPE_STRING },
- [TUNNEL_ATTR_6RD_RELAY_PREFIX] = { .name = "6rd-relay-prefix", .type = BLOBMSG_TYPE_STRING },
[TUNNEL_ATTR_LINK] = { .name = "link", .type = BLOBMSG_TYPE_STRING },
[TUNNEL_ATTR_FMRS] = { .name = "fmrs", .type = BLOBMSG_TYPE_ARRAY },
[TUNNEL_ATTR_DATA] = { .name = "data", .type = BLOBMSG_TYPE_TABLE },
@@ -70,6 +68,16 @@ const struct uci_blob_param_list vti_data_attr_list = {
.params = vti_data_attrs,
};
+static const struct blobmsg_policy sixrd_data_attrs[__SIXRD_DATA_ATTR_MAX] = {
+ [SIXRD_DATA_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING },
+ [SIXRD_DATA_RELAY_PREFIX] = { .name = "relay-prefix", .type = BLOBMSG_TYPE_STRING },
+};
+
+const struct uci_blob_param_list sixrd_data_attr_list = {
+ .n_params = __SIXRD_DATA_ATTR_MAX,
+ .params = sixrd_data_attrs,
+};
+
void system_fd_set_cloexec(int fd)
{
#ifdef FD_CLOEXEC
diff --git a/system.h b/system.h
index 9995fa9..c8ddbad 100644
--- a/system.h
+++ b/system.h
@@ -63,9 +63,16 @@ enum vti_data {
__VTI_DATA_ATTR_MAX
};
+enum sixrd_data {
+ SIXRD_DATA_PREFIX,
+ SIXRD_DATA_RELAY_PREFIX,
+ __SIXRD_DATA_ATTR_MAX
+};
+
extern const struct uci_blob_param_list vxlan_data_attr_list;
extern const struct uci_blob_param_list gre_data_attr_list;
extern const struct uci_blob_param_list vti_data_attr_list;
+extern const struct uci_blob_param_list sixrd_data_attr_list;
enum bridge_opt {
/* stp and forward delay always set */