Skip to content
This repository was archived by the owner on Jan 6, 2023. It is now read-only.

Commit 82fc16f

Browse files
amshindeJulio Montes
authored andcommitted
Add support for multiple ip addresses for a network interface
A network interface can have multiple IP addresses. Change the interface json to accept a list of IP addresses instead of a single value. Support for old format of a single interface is maintained. Signed-off-by: Archana Shinde <[email protected]>
1 parent afe2b92 commit 82fc16f

File tree

4 files changed

+134
-57
lines changed

4 files changed

+134
-57
lines changed

src/net.c

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,9 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
614614
char buf[256];
615615
} req;
616616
int ifindex;
617+
struct hyper_ipaddress *ip;
617618

618-
if (!(iface->device && iface->ipaddr && iface->mask)) {
619+
if (!iface->device || list_empty(&iface->ipaddresses)) {
619620
fprintf(stderr, "interface information incorrect\n");
620621
return -1;
621622
}
@@ -635,26 +636,28 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
635636
req.ifa.ifa_index = ifindex;
636637
req.ifa.ifa_scope = 0;
637638

638-
if (get_addr_ipv4((uint8_t *)&data, iface->ipaddr) <= 0) {
639-
fprintf(stderr, "get addr failed\n");
640-
return -1;
641-
}
639+
list_for_each_entry(ip, &iface->ipaddresses, list) {
640+
if (get_addr_ipv4((uint8_t *)&data, ip->addr) <= 0) {
641+
fprintf(stderr, "get addr failed\n");
642+
return -1;
643+
}
642644

643-
if (addattr_l(&req.n, sizeof(req), IFA_LOCAL, &data, 4)) {
644-
fprintf(stderr, "setup attr failed\n");
645-
return -1;
646-
}
645+
if (addattr_l(&req.n, sizeof(req), IFA_LOCAL, &data, 4)) {
646+
fprintf(stderr, "setup attr failed\n");
647+
return -1;
648+
}
647649

648-
if (get_netmask(&mask, iface->mask) < 0) {
649-
fprintf(stderr, "get netamsk failed\n");
650-
return -1;
651-
}
650+
if (get_netmask(&mask, ip->mask) < 0) {
651+
fprintf(stderr, "get netamsk failed\n");
652+
return -1;
653+
}
652654

653-
req.ifa.ifa_prefixlen = mask;
654-
fprintf(stdout, "interface get netamsk %d %s\n", req.ifa.ifa_prefixlen, iface->mask);
655-
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
656-
perror("rtnl_talk failed");
657-
return -1;
655+
req.ifa.ifa_prefixlen = mask;
656+
fprintf(stdout, "interface get netamsk %d %s\n", req.ifa.ifa_prefixlen, ip->mask);
657+
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
658+
perror("rtnl_talk failed");
659+
return -1;
660+
}
658661
}
659662

660663
if (iface->new_device_name && strcmp(iface->new_device_name, iface->device)) {
@@ -681,8 +684,9 @@ static int hyper_cleanup_interface(struct rtnl_handle *rth,
681684
char buf[256];
682685
} req;
683686
int ifindex;
687+
struct hyper_ipaddress *ip;
684688

685-
if (!(iface->device && iface->ipaddr && iface->mask)) {
689+
if (!iface->device || list_empty(&iface->ipaddresses)) {
686690
fprintf(stderr, "interface information incorrect\n");
687691
return -1;
688692
}
@@ -702,26 +706,28 @@ static int hyper_cleanup_interface(struct rtnl_handle *rth,
702706
req.ifa.ifa_index = ifindex;
703707
req.ifa.ifa_scope = 0;
704708

705-
if (get_addr_ipv4((uint8_t *)&data, iface->ipaddr) <= 0) {
706-
fprintf(stderr, "get addr failed\n");
707-
return -1;
708-
}
709+
list_for_each_entry(ip, &iface->ipaddresses, list) {
710+
if (get_addr_ipv4((uint8_t *)&data, ip->addr) <= 0) {
711+
fprintf(stderr, "get addr failed\n");
712+
return -1;
713+
}
709714

710-
if (addattr_l(&req.n, sizeof(req), IFA_LOCAL, &data, 4)) {
711-
fprintf(stderr, "setup attr failed\n");
712-
return -1;
713-
}
715+
if (addattr_l(&req.n, sizeof(req), IFA_LOCAL, &data, 4)) {
716+
fprintf(stderr, "setup attr failed\n");
717+
return -1;
718+
}
714719

715-
if (get_netmask(&mask, iface->mask) < 0) {
716-
fprintf(stderr, "get netamsk failed\n");
717-
return -1;
718-
}
720+
if (get_netmask(&mask, ip->mask) < 0) {
721+
fprintf(stderr, "get netamsk failed\n");
722+
return -1;
723+
}
719724

720-
req.ifa.ifa_prefixlen = mask;
721-
fprintf(stdout, "interface get netamsk %d %s\n", req.ifa.ifa_prefixlen, iface->mask);
722-
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
723-
perror("rtnl_talk failed");
724-
return -1;
725+
req.ifa.ifa_prefixlen = mask;
726+
fprintf(stdout, "interface get netamsk %d %s\n", req.ifa.ifa_prefixlen, ip->mask);
727+
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
728+
perror("rtnl_talk failed");
729+
return -1;
730+
}
725731
}
726732

727733
/* Don't down&remove lo device */
@@ -838,9 +844,7 @@ void hyper_cleanup_network(struct hyper_pod *pod)
838844
if (hyper_cleanup_interface(&rth, iface) < 0)
839845
fprintf(stderr, "link down device %s failed\n", iface->device);
840846

841-
free(iface->device);
842-
free(iface->ipaddr);
843-
free(iface->mask);
847+
hyper_free_interface(iface);
844848
}
845849

846850
free(pod->iface);
@@ -874,9 +878,7 @@ int hyper_cmd_setup_interface(char *json, int length)
874878
}
875879
ret = 0;
876880
out1:
877-
free(iface->device);
878-
free(iface->ipaddr);
879-
free(iface->mask);
881+
hyper_free_interface(iface);
880882
free(iface);
881883
out:
882884
netlink_close(&rth);

src/net.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <linux/netlink.h>
1111
#include <linux/rtnetlink.h>
1212

13+
#include "list.h"
14+
1315
struct rtnl_handle {
1416
int fd;
1517
struct sockaddr_nl local;
@@ -18,11 +20,16 @@ struct rtnl_handle {
1820
__u32 dump;
1921
};
2022

23+
struct hyper_ipaddress {
24+
struct list_head list;
25+
char *addr;
26+
char *mask;
27+
};
28+
2129
struct hyper_interface {
22-
char *device;
23-
char *ipaddr;
24-
char *mask;
25-
char *new_device_name;
30+
char *device;
31+
struct list_head ipaddresses;
32+
char *new_device_name;
2633
};
2734

2835
struct hyper_route {

src/parse.c

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -750,46 +750,113 @@ static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t *
750750
return -1;
751751
}
752752

753+
void hyper_free_interface(struct hyper_interface *iface)
754+
{
755+
struct hyper_ipaddress *ip, *tmp;
756+
757+
list_for_each_entry_safe(ip, tmp, &iface->ipaddresses , list) {
758+
free(ip->addr);
759+
free(ip->mask);
760+
list_del_init(&ip->list);
761+
}
762+
free(iface->device);
763+
free(iface->new_device_name);
764+
}
765+
753766
static int hyper_parse_interface(struct hyper_interface *iface,
754767
char *json, jsmntok_t *toks)
755768
{
756-
int i = 0, j, next_if;
769+
int i = 0, j, next_if, k, l, num_ipaddr, ipaddr_size;
770+
struct hyper_ipaddress *ipaddr = NULL;
771+
struct hyper_ipaddress *ipaddr_oldf = NULL;
757772

758773
if (toks[i].type != JSMN_OBJECT) {
759774
fprintf(stdout, "network array need object\n");
760775
return -1;
761776
}
762777

778+
INIT_LIST_HEAD(&iface->ipaddresses);
763779
next_if = toks[i].size;
764780

765781
i++;
766782
for (j = 0; j < next_if; j++, i++) {
767783
if (json_token_streq(json, &toks[i], "device")) {
768784
iface->device = (json_token_str(json, &toks[++i]));
769785
fprintf(stdout, "net device is %s\n", iface->device);
770-
} else if (json_token_streq(json, &toks[i], "ipAddress")) {
771-
iface->ipaddr = (json_token_str(json, &toks[++i]));
772-
fprintf(stdout, "net ipaddress is %s\n", iface->ipaddr);
773-
} else if (json_token_streq(json, &toks[i], "netMask")) {
774-
iface->mask = (json_token_str(json, &toks[++i]));
775-
fprintf(stdout, "net mask is %s\n", iface->mask);
786+
} else if (json_token_streq(json, &toks[i], "ipAddresses")) {
787+
if (toks[++i].type != JSMN_ARRAY) {
788+
fprintf(stdout, "interface object needs ipAddresses array\n");
789+
goto fail;
790+
}
791+
792+
num_ipaddr = toks[i].size;
793+
fprintf(stdout, "Number of ip addresses:%d\n", num_ipaddr);
794+
795+
for (k = 0; k < num_ipaddr; k++) {
796+
if (toks[++i].type != JSMN_OBJECT) {
797+
fprintf(stderr, "ipaddress is not an object\n");
798+
goto fail;
799+
}
800+
ipaddr = calloc(1, sizeof(*ipaddr));
801+
if (ipaddr == NULL) {
802+
fprintf(stderr, "Alloc memory for ipaddress failed\n");
803+
goto fail;
804+
}
805+
806+
ipaddr_size = toks[i].size;
807+
808+
for (l = 0; l < ipaddr_size; l++) {
809+
i++;
810+
if (json_token_streq(json, &toks[i], "ipAddress")) {
811+
ipaddr->addr = (json_token_str(json, &toks[++i]));
812+
fprintf(stdout, "net ipaddress for device %s is %s\n",
813+
iface->device, ipaddr->addr);
814+
} else if (json_token_streq(json, &toks[i], "netMask")) {
815+
ipaddr->mask = (json_token_str(json, &toks[++i]));
816+
fprintf(stdout, "net mask for device %s is %s\n",
817+
iface->device, ipaddr->mask);
818+
} else {
819+
fprintf(stderr, "get unknown section %s in interfaces\n",
820+
json_token_str(json, &toks[i]));
821+
free(ipaddr);
822+
goto fail;
823+
}
824+
}
825+
INIT_LIST_HEAD(&ipaddr->list);
826+
list_add_tail(&ipaddr->list, &iface->ipaddresses);
827+
}
776828
} else if (json_token_streq(json, &toks[i], "newDeviceName")) {
777829
iface->new_device_name = (json_token_str(json, &toks[++i]));
778830
fprintf(stdout, "new interface name is %s\n", iface->new_device_name);
831+
} else if (json_token_streq(json, &toks[i], "ipAddress")) {
832+
if (ipaddr_oldf == NULL) {
833+
ipaddr_oldf = calloc(1, sizeof(*ipaddr));
834+
}
835+
ipaddr_oldf->addr = (json_token_str(json, &toks[++i]));
836+
fprintf(stdout, "net ipaddress is %s\n", ipaddr_oldf->addr);
837+
} else if (json_token_streq(json, &toks[i], "netMask")) {
838+
if (ipaddr_oldf == NULL) {
839+
ipaddr_oldf = calloc(1, sizeof(*ipaddr));
840+
}
841+
ipaddr_oldf->mask = (json_token_str(json, &toks[++i]));
842+
fprintf(stdout, "net mask is %s\n", ipaddr_oldf->mask);
779843
} else {
780844
fprintf(stderr, "get unknown section %s in interfaces\n",
781845
json_token_str(json, &toks[i]));
782846
goto fail;
783847
}
784848
}
785849

850+
if (ipaddr_oldf) {
851+
INIT_LIST_HEAD(&ipaddr_oldf->list);
852+
list_add_tail(&ipaddr_oldf->list, &iface->ipaddresses);
853+
}
854+
786855
return i;
787856

788857
fail:
789-
free(iface->device);
790-
free(iface->ipaddr);
791-
free(iface->mask);
792-
free(iface->new_device_name);
858+
free(ipaddr_oldf);
859+
hyper_free_interface(iface);
793860
return -1;
794861
}
795862

src/parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ int hyper_parse_file_command(struct file_command *cmd, char *json, int length);
1414
struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length);
1515
void hyper_free_container(struct hyper_container *c);
1616
struct hyper_interface *hyper_parse_setup_interface(char *json, int length);
17+
void hyper_free_interface(struct hyper_interface *iface);
1718
int hyper_parse_setup_routes(struct hyper_route **routes, uint32_t *r_num, char *json, int length);
1819
JSON_Value *hyper_json_parse(char *json, int length);
1920

0 commit comments

Comments
 (0)