diff --git a/src/hyper.h b/src/hyper.h index cfe69be8..7b0915c1 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -34,6 +34,7 @@ enum { NEWCONTAINER, KILLCONTAINER, ONLINECPUMEM, + SETUPINTERFACE, }; enum { diff --git a/src/init.c b/src/init.c index 44e03690..642f6056 100644 --- a/src/init.c +++ b/src/init.c @@ -1137,6 +1137,9 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) case ONLINECPUMEM: hyper_cmd_online_cpu_mem(); break; + case SETUPINTERFACE: + ret = hyper_cmd_setup_interface((char *)buf->data + 8, len - 8); + break; default: ret = -1; break; diff --git a/src/net.c b/src/net.c index b4810c16..9254e8a1 100644 --- a/src/net.c +++ b/src/net.c @@ -11,6 +11,7 @@ #include "hyper.h" #include "util.h" +#include "parse.h" #include "../config.h" void hyper_set_be32(uint8_t *buf, uint32_t val) @@ -783,6 +784,40 @@ void hyper_cleanup_network(struct hyper_pod *pod) netlink_close(&rth); } +int hyper_cmd_setup_interface(char *json, int length) +{ + int ret = -1; + struct hyper_interface *iface; + struct rtnl_handle rth; + + if (hyper_rescan() < 0) + return -1; + + if (netlink_open(&rth) < 0) + return -1; + + + iface = hyper_parse_setup_interface(json, length); + if (iface == NULL) { + fprintf(stderr, "parse interface failed\n"); + goto out; + } + ret = hyper_setup_interface(&rth, iface); + if (ret < 0) { + fprintf(stderr, "link up device %s failed\n", iface->device); + goto out1; + } + ret = 0; +out1: + free(iface->device); + free(iface->ipaddr); + free(iface->mask); + free(iface); +out: + netlink_close(&rth); + return ret; +} + int hyper_setup_dns(struct hyper_pod *pod) { int i, fd, ret = -1; diff --git a/src/net.h b/src/net.h index c16fb8b6..3aeff545 100644 --- a/src/net.h +++ b/src/net.h @@ -47,6 +47,7 @@ uint32_t hyper_get_be32(uint8_t *buf); void hyper_set_be64(uint8_t *buf, uint64_t val); uint64_t hyper_get_be64(uint8_t *buf); int hyper_setup_network(struct hyper_pod *pod); +int hyper_cmd_setup_interface(char *json, int length); void hyper_cleanup_network(struct hyper_pod *pod); int hyper_setup_dns(struct hyper_pod *pod); void hyper_cleanup_dns(struct hyper_pod *pod); diff --git a/src/parse.c b/src/parse.c index 02a0a579..a05fda59 100644 --- a/src/parse.c +++ b/src/parse.c @@ -635,9 +635,92 @@ static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t * return -1; } -static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t *toks) +static int hyper_parse_interface(struct hyper_interface *iface, + char *json, jsmntok_t *toks) { int i = 0, j, next_if; + + if (toks[i].type != JSMN_OBJECT) { + fprintf(stdout, "network array need object\n"); + return -1; + } + + next_if = toks[i].size; + + i++; + for (j = 0; j < next_if; j++, i++) { + if (json_token_streq(json, &toks[i], "device")) { + iface->device = (json_token_str(json, &toks[++i])); + fprintf(stdout, "net device is %s\n", iface->device); + } else if (json_token_streq(json, &toks[i], "ipAddress")) { + iface->ipaddr = (json_token_str(json, &toks[++i])); + fprintf(stdout, "net ipaddress is %s\n", iface->ipaddr); + } else if (json_token_streq(json, &toks[i], "netMask")) { + iface->mask = (json_token_str(json, &toks[++i])); + fprintf(stdout, "net mask is %s\n", iface->mask); + } else { + fprintf(stderr, "get unknown section %s in interfaces\n", + json_token_str(json, &toks[i])); + goto fail; + } + } + + return i; + +fail: + free(iface->device); + free(iface->ipaddr); + free(iface->mask); + return -1; +} + +struct hyper_interface *hyper_parse_setup_interface(char *json, int length) +{ + jsmn_parser p; + int toks_num = 10, n; + jsmntok_t *toks = NULL; + + struct hyper_interface *iface = NULL; +realloc: + toks = realloc(toks, toks_num * sizeof(jsmntok_t)); + if (toks == NULL) { + fprintf(stderr, "allocate tokens for execcmd failed\n"); + goto fail; + } + + jsmn_init(&p); + n = jsmn_parse(&p, json, length, toks, toks_num); + if (n < 0) { + fprintf(stdout, "jsmn parse failed, n is %d\n", n); + if (n == JSMN_ERROR_NOMEM) { + toks_num *= 2; + goto realloc; + } + goto out; + } + + iface = calloc(1, sizeof(*iface)); + if (iface == NULL) { + fprintf(stderr, "allocate memory for interface failed\n"); + goto out; + } + + if (hyper_parse_interface(iface, json, toks) < 0) { + fprintf(stderr, "allocate memory for interface failed\n"); + goto fail; + } +out: + free(toks); + return iface; +fail: + free(iface); + iface = NULL; + goto out; +} + +static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t *toks) +{ + int i = 0, j, next; struct hyper_interface *iface; if (toks[i].type != JSMN_ARRAY) { @@ -656,32 +739,11 @@ static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t * i++; for (j = 0; j < pod->i_num; j++) { - int i_if; - iface = &pod->iface[j]; - - if (toks[i].type != JSMN_OBJECT) { - fprintf(stdout, "network array need object\n"); + next = hyper_parse_interface(&pod->iface[j], json, toks + i); + if (next < 0) return -1; - } - next_if = toks[i].size; - i++; - for (i_if = 0; i_if < next_if; i_if++, i++) { - if (json_token_streq(json, &toks[i], "device")) { - iface->device = (json_token_str(json, &toks[++i])); - fprintf(stdout, "net device is %s\n", iface->device); - } else if (json_token_streq(json, &toks[i], "ipAddress")) { - iface->ipaddr = (json_token_str(json, &toks[++i])); - fprintf(stdout, "net ipaddress is %s\n", iface->ipaddr); - } else if (json_token_streq(json, &toks[i], "netMask")) { - iface->mask = (json_token_str(json, &toks[++i])); - fprintf(stdout, "net mask is %s\n", iface->mask); - } else { - fprintf(stderr, "get unknown section %s in interfaces\n", - json_token_str(json, &toks[i])); - return -1; - } - } + i += next; } return i; diff --git a/src/parse.h b/src/parse.h index 52f91f93..f72eaef4 100644 --- a/src/parse.h +++ b/src/parse.h @@ -14,5 +14,6 @@ int hyper_parse_write_file(struct hyper_writter *writter, char *json, int length int hyper_parse_read_file(struct hyper_reader *reader, char *json, int length); struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length); void hyper_free_container(struct hyper_container *c); +struct hyper_interface *hyper_parse_setup_interface(char *json, int length); #endif