Skip to content

Commit 4c2b43f

Browse files
Add support for ipv6
Signed-off-by: francescomessina <francescomessina92@hotmail.com>
1 parent 47992c8 commit 4c2b43f

4 files changed

Lines changed: 69 additions & 0 deletions

File tree

src/polycubed/src/utils/netlink.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,26 @@ struct nlmsghdr* Netlink::netlink_ip_alloc() {
668668
return nlmsg;
669669
}
670670

671+
struct nlmsghdr* Netlink::netlink_ipv6_alloc() {
672+
size_t len = NLMSG_ALIGN(SIZE_ALIGN) + NLMSG_ALIGN(sizeof(struct nlmsghdr *));
673+
struct nlmsghdr *nlmsg = (struct nlmsghdr *) malloc(len);
674+
memset(nlmsg, 0, len);
675+
676+
struct nl_ipreq *uni = (struct nl_ipreq *)nlmsg;
677+
uni->ifaddrmsg.ifa_family = AF_INET6;
678+
uni->ifaddrmsg.ifa_scope = 0;
679+
680+
nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
681+
nlmsg->nlmsg_type = RTM_NEWADDR;
682+
// NLM_F_REQUEST Must be set on all request messages
683+
// NLM_F_ACK Request for an acknowledgment on success
684+
// NLM_F_CREATE Create object if it doesn't already exist
685+
// NLM_F_EXCL Don't replace if the object already exists
686+
nlmsg->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_CREATE|NLM_F_EXCL;
687+
688+
return nlmsg;
689+
}
690+
671691
int Netlink::netlink_nl_send(struct nlmsghdr *nlmsg) {
672692
struct sockaddr_nl nladdr;
673693
struct iovec iov = {
@@ -825,6 +845,41 @@ void Netlink::set_iface_ip(const std::string &iface, const std::string &ip, int
825845
netlink_nl_send(nlmsg);
826846
}
827847

848+
void Netlink::set_iface_ipv6(const std::string &iface, const std::string &ipv6) {
849+
struct nlmsghdr *nlmsg = netlink_ipv6_alloc();
850+
struct nl_ipreq *uni = (struct nl_ipreq *)nlmsg;
851+
struct rtattr *rta;
852+
struct in6_addr ia;
853+
854+
int index = get_iface_index(iface);
855+
if (index == -1) {
856+
logger->error("set_iface_ipv6: iface {0} does not exist", iface);
857+
throw std::runtime_error("set_iface_ipv6: iface does not exist");
858+
}
859+
860+
uni->ifaddrmsg.ifa_index = index;
861+
862+
if (inet_pton(AF_INET6, ipv6.c_str(), &ia) <= 0) {
863+
free(nlmsg);
864+
logger->error("set_iface_ipv6: Error in inet_pton");
865+
throw std::runtime_error("set_iface_ipv6: Error in inet_pton");
866+
}
867+
868+
rta = NLMSG_TAIL(nlmsg);
869+
rta->rta_type = IFA_LOCAL;
870+
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
871+
memcpy(RTA_DATA(rta), &ia, sizeof(struct in6_addr));
872+
nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_ALIGN(rta->rta_len);
873+
874+
rta = NLMSG_TAIL(nlmsg);
875+
rta->rta_type = IFA_ADDRESS;
876+
rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
877+
memcpy(RTA_DATA(rta), &ia, sizeof(struct in6_addr));
878+
nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_ALIGN(rta->rta_len);
879+
880+
netlink_nl_send(nlmsg);
881+
}
882+
828883
void Netlink::move_iface_into_ns(const std::string &iface, int fd) {
829884
struct nlmsghdr *nlmsg = netlink_alloc();
830885
struct nl_req *unr = (struct nl_req *)nlmsg;

src/polycubed/src/utils/netlink.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class Netlink {
8080
void set_iface_status(const std::string &iface, IFACE_STATUS status);
8181
void set_iface_mac(const std::string &iface, const std::string &mac);
8282
void set_iface_ip(const std::string &iface, const std::string &ip, int prefix);
83+
void set_iface_ipv6(const std::string &iface, const std::string &ip);
8384
void move_iface_into_ns(const std::string &iface, int fd);
8485

8586
template <typename Observer>
@@ -122,6 +123,7 @@ class Netlink {
122123

123124
struct nlmsghdr* netlink_alloc();
124125
struct nlmsghdr* netlink_ip_alloc();
126+
struct nlmsghdr* netlink_ipv6_alloc();
125127
int netlink_nl_send(struct nlmsghdr *nlmsg);
126128

127129
std::shared_ptr<spdlog::logger> logger;

src/polycubed/src/utils/veth.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ void VethPeer::set_ip(const std::string &ip, const int prefix) {
8080
}
8181
}
8282

83+
void VethPeer::set_ipv6(const std::string &ipv6) {
84+
if (!ns_.empty()) {
85+
/* exec set_iface_ipv6 into namespace */
86+
std::function<void()> doThis = [&]{Netlink::getInstance().set_iface_ipv6(name_, ipv6);};
87+
Namespace namespace_ = Namespace::open(ns_);
88+
namespace_.execute(doThis);
89+
} else {
90+
Netlink::getInstance().set_iface_ipv6(name_, ipv6);
91+
}
92+
}
93+
8394
/* Class Veth */
8495
Veth Veth::create(const std::string &peerA, const std::string &peerB) {
8596
struct rtnl_link *link;

src/polycubed/src/utils/veth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class VethPeer {
3737
void set_status(IFACE_STATUS status);
3838
void set_mac(const std::string &mac);
3939
void set_ip(const std::string &ip, const int prefix);
40+
void set_ipv6(const std::string &ipv6);
4041

4142
private:
4243
std::string name_;

0 commit comments

Comments
 (0)