Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum {
REMOVECONTAINER,
PROCESSASYNCEVENT,
SIGNALPROCESS,
DELETEINTERFACE, // 25
};

// "hyperstart" is the special container ID for adding processes.
Expand Down
3 changes: 3 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,9 @@ static int hyper_ctlmsg_handle(struct hyper_event *he, uint32_t len)
case SETUPINTERFACE:
ret = hyper_cmd_setup_interface((char *)buf->data + 8, len - 8, pod);
break;
case DELETEINTERFACE:
ret = hyper_cmd_delete_interface((char *)buf->data + 8, len - 8);
break;
case SETUPROUTE:
ret = hyper_cmd_setup_route((char *)buf->data + 8, len - 8, pod);
break;
Expand Down
171 changes: 130 additions & 41 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,64 @@ static int hyper_set_interface_attr(struct rtnl_handle *rth,
return 0;
}

static int hyper_set_interface_ipaddrs(struct rtnl_handle *rth,
int ifindex,
struct list_head* ipaddresses){
uint8_t data[4];
unsigned mask;
struct {
struct nlmsghdr n;
struct ifaddrmsg ifa;
char buf[256];
} req;
struct hyper_ipaddress *ip;

memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
req.ifa.ifa_family = AF_INET;
req.ifa.ifa_index = ifindex;
req.ifa.ifa_scope = 0;

list_for_each_entry(ip, ipaddresses, list) {
if (ip->addr[0]=='\0'){
continue;
} else if (ip->addr[0]=='-') {
//start with '-' means delete an existing address
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_DELADDR;;
if (get_addr_ipv4((uint8_t *)&data, &ip->addr[1]) <= 0) {
fprintf(stderr, "get addr failed\n");
return -1;
}
} else{
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
req.n.nlmsg_type = RTM_NEWADDR;
if (get_addr_ipv4((uint8_t *)&data, ip->addr) <= 0) {
fprintf(stderr, "get addr failed\n");
return -1;
}
}

if (addattr_l(&req.n, sizeof(req), IFA_LOCAL, &data, 4)) {
fprintf(stderr, "setup attr failed\n");
return -1;
}

if (get_netmask(&mask, ip->mask) < 0) {
fprintf(stderr, "get netamsk failed\n");
return -1;
}

req.ifa.ifa_prefixlen = mask;
fprintf(stdout, "interface get netamsk %d %s\n", req.ifa.ifa_prefixlen, ip->mask);
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
perror("rtnl_talk failed");
return -1;
}
}
return 0;
}

static int hyper_set_interface_name(struct rtnl_handle *rth,
int ifindex,
char *new_device_name)
Expand Down Expand Up @@ -452,56 +510,22 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
struct hyper_interface *iface,
struct hyper_pod *pod)
{
uint8_t data[4];
unsigned mask;
struct {
struct nlmsghdr n;
struct ifaddrmsg ifa;
char buf[256];
} req;
int ifindex;
struct hyper_ipaddress *ip;

if (!iface->device || list_empty(&iface->ipaddresses)) {
fprintf(stderr, "interface information incorrect\n");
if (!iface->device) {
fprintf(stderr, "device name can't be empty\n");
return -1;
}

memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
req.n.nlmsg_type = RTM_NEWADDR;
req.ifa.ifa_family = AF_INET;

ifindex = hyper_get_ifindex(iface->device, pod);
if (ifindex < 0) {
fprintf(stderr, "failed to get the ifindix of %s\n", iface->device);
return -1;
}

req.ifa.ifa_index = ifindex;
req.ifa.ifa_scope = 0;

list_for_each_entry(ip, &iface->ipaddresses, list) {
if (get_addr_ipv4((uint8_t *)&data, ip->addr) <= 0) {
fprintf(stderr, "get addr failed\n");
return -1;
}

if (addattr_l(&req.n, sizeof(req), IFA_LOCAL, &data, 4)) {
fprintf(stderr, "setup attr failed\n");
return -1;
}

if (get_netmask(&mask, ip->mask) < 0) {
fprintf(stderr, "get netamsk failed\n");
return -1;
}

req.ifa.ifa_prefixlen = mask;
fprintf(stdout, "interface get netamsk %d %s\n", req.ifa.ifa_prefixlen, ip->mask);
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
perror("rtnl_talk failed");
if (!list_empty(&iface->ipaddresses)) {
if (hyper_set_interface_ipaddrs(rth, ifindex, &iface->ipaddresses) < 0) {
fprintf(stderr, "set ip addresses failed for interface %s\n",
iface->device);
return -1;
}
}
Expand Down Expand Up @@ -603,7 +627,6 @@ int hyper_cmd_setup_interface(char *json, int length, struct hyper_pod *pod)
if (netlink_open(&rth) < 0)
return -1;


iface = hyper_parse_setup_interface(json, length);
if (iface == NULL) {
fprintf(stderr, "parse interface failed\n");
Expand All @@ -623,6 +646,71 @@ int hyper_cmd_setup_interface(char *json, int length, struct hyper_pod *pod)
return ret;
}

static int hyper_remove_nic(char *device)
{
char path[256], real[128];
int fd;
ssize_t size;

sprintf(path, "/sys/class/net/%s", device);

size = readlink(path, real, 128);
if (size < 0 || size > 127) {
perror("fail to read link directory");
return -1;
}

real[size] = '\0';
sprintf(path, "/sys/%s/../../../remove", real + 5);

fprintf(stdout, "get net sys path %s\n", path);

fd = open(path, O_WRONLY);
if (fd < 0) {
perror("open file failed");
return -1;
}

if (write(fd, "1\n", 2) < 0) {
perror("write 1 to file failed");
close(fd);
return 1;
}

close(fd);
return 0;
}

int hyper_cmd_delete_interface(char *json, int length)
{
int ret = -1;
struct hyper_interface *iface;
struct rtnl_handle rth;

fprintf(stdout, "client demands to remove network interface\n");
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;
}

if (hyper_remove_nic(iface->device) < 0){
fprintf(stderr, "remove device %s failed\n", iface->device);
goto out1;
}
fprintf(stdout, "remove device %s successfully\n", iface->device);
ret = 0;
out1:
hyper_free_interface(iface);
free(iface);
out:
netlink_close(&rth);
return ret;
}

int hyper_cmd_setup_route(char *json, int length, struct hyper_pod *pod)
{
struct hyper_route *rts = NULL;
Expand Down Expand Up @@ -780,3 +868,4 @@ int hyper_setup_dns(struct hyper_pod *pod)
close(fd);
return ret;
}

1 change: 1 addition & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ int hyper_setup_dns(struct hyper_pod *pod);
int hyper_setup_hostname(struct hyper_pod *pod);
int hyper_send_data_block(int fd, uint8_t *data, uint32_t len);
int hyper_send_data(int fd, uint8_t *data, uint32_t len);
int hyper_cmd_delete_interface(char *json, int length);
#endif