@@ -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+
671691int 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+
828883void 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;
0 commit comments