From 53ffb48e0a28ae3c18fbf2483dba3d6dd5dd7c36 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 23 May 2016 19:32:42 +0800 Subject: [PATCH 1/2] support setup routes separately Signed-off-by: Gao feng --- src/hyper.h | 1 + src/init.c | 3 ++ src/net.c | 29 +++++++++++++++++++ src/net.h | 1 + src/parse.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--------- src/parse.h | 1 + 6 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/hyper.h b/src/hyper.h index 431a429..51e5471 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -35,6 +35,7 @@ enum { KILLCONTAINER, ONLINECPUMEM, SETUPINTERFACE, + SETUPROUTE, }; enum { diff --git a/src/init.c b/src/init.c index 642f605..ef58481 100644 --- a/src/init.c +++ b/src/init.c @@ -1140,6 +1140,9 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) case SETUPINTERFACE: ret = hyper_cmd_setup_interface((char *)buf->data + 8, len - 8); break; + case SETUPROUTE: + ret = hyper_cmd_setup_route((char *)buf->data + 8, len - 8); + break; default: ret = -1; break; diff --git a/src/net.c b/src/net.c index 9254e8a..e6d890e 100644 --- a/src/net.c +++ b/src/net.c @@ -818,6 +818,35 @@ out: return ret; } +int hyper_cmd_setup_route(char *json, int length) { + struct hyper_route *rts = NULL; + int i, ret = -1; + uint32_t r_num; + struct rtnl_handle rth; + + if (netlink_open(&rth) < 0) + return -1; + + if (hyper_parse_setup_routes(&rts, &r_num, json, length) < 0) { + fprintf(stderr, "parse route failed\n"); + goto out; + } + + for (i = 0; i < r_num; i++) { + ret = hyper_setup_route(&rth, &rts[i]); + if (ret < 0) { + fprintf(stderr, "setup route failed\n"); + goto out; + } + } + + ret = 0; +out: + netlink_close(&rth); + free(rts); + 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 3aeff54..0de6fbf 100644 --- a/src/net.h +++ b/src/net.h @@ -48,6 +48,7 @@ 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); +int hyper_cmd_setup_route(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 0f7830a..2ff4557 100644 --- a/src/parse.c +++ b/src/parse.c @@ -797,33 +797,33 @@ static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t * return i; } -static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks) +static int hyper_parse_routes(struct hyper_route **routes, uint32_t *r_num, char *json, jsmntok_t *toks) { - int i = 0, j, next_rt; - struct hyper_route *rt; + int i = 0, j, num, next_rt; + struct hyper_route *rts; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "routes need array\n"); return -1; } - pod->r_num = toks[i].size; - fprintf(stdout, "network routes num %d\n", pod->r_num); + num = toks[i].size; + fprintf(stdout, "network routes num %d\n", num); - pod->rt = calloc(pod->r_num, sizeof(*rt)); - if (pod->rt == NULL) { - fprintf(stdout, "alloc memory for router failed\n"); + rts = calloc(num, sizeof(*rts)); + if (rts == NULL) { + fprintf(stdout, "alloc memory for route failed\n"); return -1; } i++; - for (j = 0; j < pod->r_num; j++) { + for (j = 0; j < num; j++) { int i_rt; + struct hyper_route *rt = &rts[j]; - rt = &pod->rt[j]; if (toks[i].type != JSMN_OBJECT) { fprintf(stdout, "routes array need object\n"); - return -1; + goto out; } next_rt = toks[i].size; @@ -841,12 +841,67 @@ static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks } else { fprintf(stderr, "get unknown section %s in routes\n", json_token_str(json, &toks[i])); - return -1; + goto out; } } } + *routes = rts; + *r_num = num; + return i; +out: + free(rts); + return -1; +} + +int hyper_parse_setup_routes(struct hyper_route **routes, uint32_t *r_num, char *json, int length) +{ + jsmn_parser p; + int toks_num = 10, i, n, ret = -1; + jsmntok_t *toks = NULL; + +realloc: + toks = realloc(toks, toks_num * sizeof(jsmntok_t)); + if (toks == NULL) { + fprintf(stderr, "allocate tokens for setup route failed\n"); + goto out; + } + + 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; + } + + for (i = 0; i < n; i++) { + jsmntok_t *t = &toks[i]; + + if (t->type != JSMN_STRING) + continue; + + if (i++ == n || !json_token_streq(json, t, "routes")) { + fprintf(stderr, "cannot find routes\n"); + goto out; + } + + break; + } + + if (hyper_parse_routes(routes, r_num, json, &toks[i]) < 0) { + fprintf(stdout, "fail to parse routes\n"); + goto out; + } + + ret = 0; +out: + free(toks); + return ret; } static int hyper_parse_dns(struct hyper_pod *pod, char *json, jsmntok_t *toks) @@ -930,7 +985,7 @@ realloc: i += next; } else if (json_token_streq(json, t, "routes") && t->size == 1) { - next = hyper_parse_routes(pod, json, &toks[++i]); + next = hyper_parse_routes(&pod->rt, &pod->r_num, json, &toks[++i]); if (next < 0) goto out; diff --git a/src/parse.h b/src/parse.h index f72eaef..a7a9875 100644 --- a/src/parse.h +++ b/src/parse.h @@ -15,5 +15,6 @@ 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); +int hyper_parse_setup_routes(struct hyper_route **routes, uint32_t *r_num, char *json, int length); #endif From 0896a874c7187020cb2d14225aed3c093d2a7154 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 23 May 2016 19:35:48 +0800 Subject: [PATCH 2/2] fix incorrect error message Signed-off-by: Gao feng --- src/parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parse.c b/src/parse.c index 2ff4557..0ccd337 100644 --- a/src/parse.c +++ b/src/parse.c @@ -732,7 +732,7 @@ struct hyper_interface *hyper_parse_setup_interface(char *json, int length) realloc: toks = realloc(toks, toks_num * sizeof(jsmntok_t)); if (toks == NULL) { - fprintf(stderr, "allocate tokens for execcmd failed\n"); + fprintf(stderr, "allocate tokens for setup interface failed\n"); goto fail; } @@ -754,7 +754,7 @@ realloc: } if (hyper_parse_interface(iface, json, toks) < 0) { - fprintf(stderr, "allocate memory for interface failed\n"); + fprintf(stderr, "parse interface failed\n"); goto fail; } out: