Add iptables setup for port mapping

This commit is contained in:
Pengfei Ni
2016-05-29 09:18:30 +00:00
parent 623d667fa0
commit 95394c8e5a
9 changed files with 300 additions and 8 deletions
+3 -2
View File
@@ -768,7 +768,7 @@ struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id)
return NULL;
}
void hyper_cleanup_container(struct hyper_container *c)
void hyper_cleanup_container(struct hyper_container *c, struct hyper_pod *pod)
{
char root[512];
@@ -777,6 +777,7 @@ void hyper_cleanup_container(struct hyper_container *c)
perror("umount devpts failed");
close(c->ns);
hyper_cleanup_container_portmapping(c, pod);
hyper_free_container(c);
}
@@ -785,7 +786,7 @@ void hyper_cleanup_containers(struct hyper_pod *pod)
struct hyper_container *c, *n;
list_for_each_entry_safe(c, n, &pod->containers, list)
hyper_cleanup_container(c);
hyper_cleanup_container(c, pod);
pod->remains = 0;
}
+9 -1
View File
@@ -24,6 +24,12 @@ struct sysctl {
char *value;
};
struct port {
int host_port;
int container_port;
char *protocol;
}
struct hyper_container {
char *id;
char *rootfs;
@@ -33,9 +39,11 @@ struct hyper_container {
struct volume *vols;
struct fsmap *maps;
struct sysctl *sys;
struct port *ports;
int vols_num;
int maps_num;
int sys_num;
int ports_num;
int ns;
int initialize;
uint32_t code;
@@ -48,7 +56,7 @@ struct hyper_pod;
int hyper_start_container(struct hyper_container *container,
int utsns, int ipcns, struct hyper_pod *pod);
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id);
void hyper_cleanup_container(struct hyper_container *container);
void hyper_cleanup_container(struct hyper_container *container, struct hyper_pod *pod);
void hyper_cleanup_containers(struct hyper_pod *pod);
void hyper_free_container(struct hyper_container *c);
+2
View File
@@ -12,6 +12,7 @@
#include "exec.h"
#include "event.h"
#include "container.h"
#include "portmapping.h"
enum {
RESERVED,
@@ -59,6 +60,7 @@ struct hyper_pod {
uint32_t r_num;
uint32_t e_num;
uint32_t d_num;
uint32_t w_num;
uint32_t type;
/* how many containers are running */
uint32_t remains;
+12 -1
View File
@@ -363,6 +363,11 @@ int hyper_start_container_stage0(struct hyper_container *c, struct hyper_pod *po
goto out;
}
if (hyper_setup_container_portmapping(c, pod) < 0) {
perror("fail to setup port mapping for container");
goto out;
}
pid = clone(hyper_container_stage0, stack + stacksize, CLONE_VM| CLONE_FILES| SIGQUIT, &arg);
if (pid < 0) {
perror("enter container pid ns failed");
@@ -577,6 +582,11 @@ static int hyper_setup_pod(struct hyper_pod *pod)
return -1;
}
if (hyper_setup_portmapping(pod) < 0) {
fprintf(stderr, "setup port mapping failed\n");
return -1;
}
if (hyper_setup_container(pod) < 0) {
fprintf(stderr, "start container failed\n");
return -1;
@@ -657,7 +667,7 @@ static int hyper_new_container(char *json, int length)
ret = hyper_start_container_stage0(c, pod);
if (ret < 0) {
//TODO full grace cleanup
hyper_cleanup_container(c);
hyper_cleanup_container(c, pod);
}
return ret;
@@ -960,6 +970,7 @@ void hyper_cleanup_pod(struct hyper_pod *pod)
hyper_cleanup_network(pod);
hyper_cleanup_shared(pod);
hyper_cleanup_dns(pod);
hyper_cleanup_portmapping(pod);
hyper_cleanup_hostname(pod);
}
+72 -4
View File
@@ -524,6 +524,68 @@ static int hyper_parse_process(struct hyper_exec *exec, char *json, jsmntok_t *t
return i;
}
static void container_free_ports(struct hyper_container *c)
{
int i;
for (i = 0; i < c->ports_num; i++) {
free(c->ports[i].protocol);
}
free(c->ports);
c->ports = NULL;
c->ports_num = 0;
}
static int container_parse_ports(struct hyper_container *c, char *json, jsmntok_t *toks)
{
int i = 0, j;
if (toks[i].type != JSMN_ARRAY) {
fprintf(stdout, "ports need array\n");
return -1;
}
c->ports = calloc(toks[i].size, sizeof(*c->ports));
if (c->ports == NULL) {
fprintf(stderr, "allocate memory for ports failed\n");
return -1;
}
c->ports_num = toks[i].size;
fprintf(stdout, "ports num %d\n", c->ports_num);
i++;
for (j = 0; j < c->ports_num; j++) {
int i_port, next_port;
if (toks[i].type != JSMN_OBJECT) {
fprintf(stdout, "port array need object\n");
return -1;
}
next_port = toks[i].size;
i++;
for (i_port = 0; i_port < next_port; i_port++, i++) {
if (json_token_streq(json, &toks[i], "protocol")) {
c->ports[j].protocol =
(json_token_str(json, &toks[++i]));
fprintf(stdout, "port %d protocol %s\n", j, c->ports[j].protocol);
} else if (json_token_streq(json, &toks[i], "hostPort")) {
c->ports[j].host_port = json_token_int(json, &toks[++i]);
fprintf(stdout, "port %d host_port %d\n", j, c->ports[j].host_port);
} else if (json_token_streq(json, &toks[i], "containerPort")) {
c->ports[j].container_port = json_token_int(json, &toks[++i]);
fprintf(stdout, "port %d container_port %d\n", j, c->ports[j].container_port);
} else {
fprintf(stdout, "get unknown section %s in ports\n",
json_token_str(json, &toks[i]));
return -1;
}
}
}
return i;
}
void hyper_free_container(struct hyper_container *c)
{
free(c->id);
@@ -542,6 +604,7 @@ void hyper_free_container(struct hyper_container *c)
c->fstype = NULL;
container_free_volumes(c);
container_free_ports(c);
container_free_sysctl(c);
container_free_fsmap(c);
container_cleanup_exec(&c->exec);
@@ -636,6 +699,11 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container *
fprintf(stdout, "need to initialize container\n");
}
i++;
} else if (json_token_streq(json, t, "ports") && t->size == 1) {
next = container_parse_ports(c, json, &toks[++i]);
if (next < 0)
goto fail;
i += next;
} else {
fprintf(stdout, "get unknown section %s in container\n",
json_token_str(json, t));
@@ -940,17 +1008,17 @@ static int hyper_parse_white_cidrs(struct hyper_pod *pod, char *json, jsmntok_t
return -1;
}
pod->d_num = toks[i].size;
fprintf(stdout, "white cidr count %d\n", pod->d_num);
pod->w_num = toks[i].size;
fprintf(stdout, "white cidr count %d\n", pod->w_num);
pod->white_cidrs = calloc(pod->d_num, sizeof(*pod->white_cidrs));
pod->white_cidrs = calloc(pod->w_num, sizeof(*pod->white_cidrs));
if (pod->white_cidrs == NULL) {
fprintf(stdout, "alloc memory for white_cidrs failed\n");
return -1;
}
i++;
for (j = 0; j < pod->d_num; j++, i++) {
for (j = 0; j < pod->w_num; j++, i++) {
pod->white_cidrs[j] = (json_token_str(json, &toks[i]));
fprintf(stdout, "pod white_cidr %d: %s\n", j, pod->dns[j]);
}
+172
View File
@@ -0,0 +1,172 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "hyper.h"
#include "util.h"
#include "../config.h"
int hyper_init_iptables()
{
const char *cmd = "/sbin/modprobe iptable_filter iptable_nat xt_multiport xt_REDIRECT";
fprintf(stdout, "command for init iptables is %s\n", cmd);
int status = hyper_cmd(cmd);
if (status < 0) {
fprintf(stderr, "modprobe iptables exit unexpectedly, status %d\n", status);
}
return status
}
int hyper_insert_rule(struct ipt_rule rule)
{
char check_cmd[512] = {0};
char cmd[512] = {0};
int check = -1;
if rule.rule != NULL {
sprintf(check_cmd, "/iptables -t %s -C %s %s", rule.table, rule.chain, rule.rule);
sprintf(cmd, "/iptables -t %s %s %s %s", rule.table, rule.op, rule.chain, rule.rule);
} else {
sprintf(cmd, "/iptables -t %s %s %s", rule.table, rule.op, rule.chain);
}
if (strlen(check_cmd) > 0) {
check = hyper_cmd(check_cmd);
fprintf(stdout, "check iptables '%s' status %d\n", check_cmd, status);
}
if check == 0 {
fprintf(stdout, "iptables rule '%s' already exist\n", rule.rule);
return 0;
}
int status = hyper_cmd(cmd);
fprintf(stdout, "insert iptables '%s' status %d\n", cmd, status);
if (status < 0) {
fprintf(stderr, "insert iptables rule failed, status %d\n", status);
}
return status
}
// load iptables modules and initialize iptables chain
int hyper_setup_portmapping(struct hyper_pod *pod)
{
if pod->w_num == 0 {
return 0;
}
if (hyper_init_iptables() < 0) {
fprintf(stderr, "modprobe iptables modules failed\n");
return -1;
}
// "/iptables -t filter -N hyperstart-INPUT",
// "/iptables -t nat -N hyperstart-PREROUTING",
// "/iptables -t filter -I INPUT -j hyperstart-INPUT",
// "/iptables -t nat -I PREROUTING -j hyperstart-PREROUTING",
// "/iptables -t filter -A hyperstart-INPUT -j DROP ",
// "/iptables -t nat -A hyperstart-PREROUTING -j RETURN"};
const struct ipt_rule rules[] = {
{
.table = "filter",
.op = "-N",
.chain = "hyperstart-INPUT",
.rule = NULL,
},
{
.table = "nat",
.op = "-N",
.chain = "hyperstart-PREROUTING",
.rule = NULL,
},
{
.table = "filter",
.op = "-I",
.chain = "INPUT",
.rule = "-j hyperstart-INPUT",
},
{
.table = "nat",
.op = "-I",
.chain = "PREROUTING",
.rule = "-j hyperstart-PREROUTING",
},
{
.table = "filter",
.op = "-A",
.chain = "hyperstart-INPUT",
.rule = "-j DROP",
},
{
.table = "nat",
.op = "-A",
.chain = "hyperstart-PREROUTING",
.rule = "-j RETURN",
},
}
for(int i=0; i< sizeof(rules)/sizeof(struct ipt_rule); i++) {
if (hyper_insert_rule(rules[i])<0) {
fprintf(stderr, "insert iptables rule '%s' failed\n", rules[i].rule);
return -1;
}
}
return 0;
}
void hyper_cleanup_portmapping(struct hyper_pod *pod)
{
int status = 0;
if pod->w_num == 0 {
return 0;
}
// const char* rules[] = {"/iptables -t filter -D hyperstart-INPUT -j DROP ",
// "/iptables -t nat -D hyperstart-PREROUTING -j RETURN",
// "/iptables -t filter -D INPUT -j hyperstart-DNPUT",
// "/iptables -t nat -D PREROUTING -j hyperstart-PREROUTING",
// "/iptables -t filter -F hyperstart-INPUT",
// "/iptables -t nat -F hyperstart-PREROUTING",
// "/iptables -t filter -X hyperstart-INPUT",
// "/iptables -t nat -X hyperstart-PREROUTING",};
}
// iptables -t filter -I hyperstart-INPUT -s 0.0.0.0/0 -p tcp -m multiport --dports 80 -j ACCEPT
// iptables -t nat -I hyperstart-PREROUTING -p tcp -m tcp --dport 8080 -j REDIRECT --to-ports 80
int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod)
{
if pod->w_num == 0 {
return 0;
}
if c->ports_num == 0 {
return 0;
}
return 0;
}
int hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod)
{
if pod->w_num == 0 {
return 0;
}
if c->ports_num == 0 {
return 0;
}
return 0;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef _PORT_MAPPING_H_
#define _PORT_MAPPING_H_
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <sys/types.h>
struct ipt_rule {
char *table;
char *op;
char *chain;
char *rule;
};
struct hyper_pod;
struct hyper_container;
int hyper_setup_portmapping(struct hyper_pod *pod);
void hyper_cleanup_portmapping(struct hyper_pod *pod);
int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod);
int hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod);
#endif
+6
View File
@@ -625,3 +625,9 @@ void hyper_shutdown()
hyper_unmount_all();
reboot(LINUX_REBOOT_CMD_POWER_OFF);
}
int hyper_cmd(char *cmd)
{
int status = system(cmd);
return ((WIFEXITED(status)) ? ((char)WEXITSTATUS(status)) : -1);
}
+1
View File
@@ -33,6 +33,7 @@ int hyper_setfd_nonblock(int fd);
int hyper_socketpair(int domain, int type, int protocol, int sv[2]);
void hyper_shutdown(void);
int hyper_insmod(char *module);
int hyper_cmd(char* cmd);
struct passwd *hyper_getpwnam(const char *name);
struct group *hyper_getgrnam(const char *name);
int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);