Skip to content

Commit

Permalink
Merge pull request #132 from francescomessina/veth_library
Browse files Browse the repository at this point in the history
Add veth library
  • Loading branch information
frisso committed May 29, 2019
2 parents c7229d5 + 65572db commit ead77a8
Show file tree
Hide file tree
Showing 28 changed files with 842 additions and 24 deletions.
8 changes: 5 additions & 3 deletions src/polycubed/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ set(polycubed_sources
extiface.cpp
extiface_tc.cpp
extiface_xdp.cpp
extiface_info.cpp
netlink.cpp
service_controller.cpp
patchpanel.cpp
datapath_log.cpp
utils.cpp
id_generator.cpp
utils/extiface_info.cpp
utils/ns.cpp
utils/veth.cpp
utils/netlink.cpp
utils/utils.cpp
${server_sources}
${CMAKE_CURRENT_BINARY_DIR}/load_services.cpp
${CMAKE_CURRENT_BINARY_DIR}/version.cpp)
Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#include "cube_tc.h"
#include "cube_xdp.h"
#include "datapath_log.h"
#include "netlink.h"
#include "patchpanel.h"
#include "utils/netlink.h"

#include "polycube/services/utils.h"

Expand Down
5 changes: 2 additions & 3 deletions src/polycubed/src/extiface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@
#include "extiface.h"
#include "bcc_mutex.h"
#include "exceptions.h"
#include "netlink.h"
#include "extiface_tc.h"
#include "patchpanel.h"
#include "port.h"

#include "extiface_tc.h"
#include "utils/netlink.h"

#include <iostream>

Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/extiface_tc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#include "extiface_tc.h"
#include "bcc_mutex.h"
#include "exceptions.h"
#include "netlink.h"
#include "patchpanel.h"
#include "utils/netlink.h"

#include <iostream>

Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/extiface_xdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#include "bcc_mutex.h"
#include "exceptions.h"
#include "extiface_tc.h"
#include "netlink.h"
#include "patchpanel.h"
#include "utils/netlink.h"

#include <iostream>

Expand Down
4 changes: 2 additions & 2 deletions src/polycubed/src/polycubed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@

#include "config.h"
#include "polycube/services/json.hpp"
#include "netlink.h"
#include "rest_server.h"
#include "utils.h"
#include "version.h"
#include "utils/netlink.h"
#include "utils/utils.h"

#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_sinks.h>
Expand Down
1 change: 1 addition & 0 deletions src/polycubed/src/polycubed_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "polycubed_core.h"
#include "config.h"
#include "rest_server.h"
#include "utils/netlink.h"

#include "server/Resources/Body/ListResource.h"
#include "server/Resources/Body/ParentResource.h"
Expand Down
3 changes: 1 addition & 2 deletions src/polycubed/src/polycubed_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
#include "service_controller.h"

#include "cube_factory_impl.h"
#include "extiface_info.h"
#include "netlink.h"
//#include "extiface_info.h"

using json = nlohmann::json;

Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/port_xdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/

#include "port_xdp.h"
#include "netlink.h"

#include "cube_xdp.h"
#include "utils/netlink.h"

namespace polycube {
namespace polycubed {
Expand Down
1 change: 1 addition & 0 deletions src/polycubed/src/rest_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "polycubed_core.h"
#include "service_controller.h"
#include "version.h"
#include "utils/netlink.h"

#include "polycube/services/response.h"
#include "server/Resources/Data/AbstractFactory.h"
Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/server/Parser/YangNodes.tcpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "../Resources/Endpoint/ParentResource.h"
#include "../Resources/Endpoint/Service.h"

#include "server/../utils.h"
#include "server/../utils/utils.h"

namespace polycube::polycubed::Rest::Parser {
std::int16_t Yang::GetExtensionIndex(lys_ext_instance **extensions,
Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/service_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

#include "config.h"
#include "cube_factory_impl.h"
#include "netlink.h"
#include "port_xdp.h"
#include "utils/netlink.h"

#include <regex>

Expand Down
2 changes: 1 addition & 1 deletion src/polycubed/src/service_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ using polycube::service::PortType;
#include "polycube/services/json.hpp"
#include "port_tc.h"
#include "port_xdp.h"
#include "utils.h"
#include "utils/utils.h"

namespace polycube {
namespace polycubed {
Expand Down
File renamed without changes.
File renamed without changes.
233 changes: 232 additions & 1 deletion src/polycubed/src/netlink.cpp → src/polycubed/src/utils/netlink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,29 @@
#include <arpa/inet.h>
#include <sstream>
#include <sys/socket.h>
#include <netinet/ether.h>

#include "exceptions.h"
#include "../exceptions.h"

#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif

/*useful for memory paging*/
#define SIZE_ALIGN 8192
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))

struct nl_req {
struct nlmsghdr nlmsg;
struct ifinfomsg ifinfomsg;
};

struct nl_ipreq {
struct nlmsghdr nlmsg;
struct ifaddrmsg ifaddrmsg;
};

namespace polycube {
namespace polycubed {

Expand Down Expand Up @@ -616,5 +632,220 @@ void Netlink::detach_from_xdp(const std::string &iface, int attach_flags) {
logger->debug("XDP program detached from port: {0}", iface);
}

struct nlmsghdr* Netlink::netlink_alloc() {
size_t len = NLMSG_ALIGN(SIZE_ALIGN) + NLMSG_ALIGN(sizeof(struct nlmsghdr *));
struct nlmsghdr *nlmsg = (struct nlmsghdr *) malloc(len);
memset(nlmsg, 0, len);

struct nl_req *unr = (struct nl_req *)nlmsg;
unr->ifinfomsg.ifi_family = AF_UNSPEC;
nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsg_type = RTM_NEWLINK;
// NLM_F_REQUEST Must be set on all request messages
// NLM_F_ACK Request for an acknowledgment on success
nlmsg->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;

return nlmsg;
}

struct nlmsghdr* Netlink::netlink_ip_alloc() {
size_t len = NLMSG_ALIGN(SIZE_ALIGN) + NLMSG_ALIGN(sizeof(struct nlmsghdr *));
struct nlmsghdr *nlmsg = (struct nlmsghdr *) malloc(len);
memset(nlmsg, 0, len);

struct nl_ipreq *uni = (struct nl_ipreq *)nlmsg;
uni->ifaddrmsg.ifa_family = AF_INET;
uni->ifaddrmsg.ifa_scope = 0;

nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
nlmsg->nlmsg_type = RTM_NEWADDR;
// NLM_F_REQUEST Must be set on all request messages
// NLM_F_ACK Request for an acknowledgment on success
// NLM_F_CREATE Create object if it doesn't already exist
// NLM_F_EXCL Don't replace if the object already exists
nlmsg->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_CREATE|NLM_F_EXCL;

return nlmsg;
}

int Netlink::netlink_nl_send(struct nlmsghdr *nlmsg) {
struct sockaddr_nl nladdr;
struct iovec iov = {
.iov_base = (void*)nlmsg,
.iov_len = nlmsg->nlmsg_len,
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
int nlfd;

memset(&nladdr, 0, sizeof(struct sockaddr_nl));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0;
nladdr.nl_groups = 0;

nlfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (nlfd < 0) {
free(nlmsg);
logger->error("netlink_nl_send: Unable to open socket");
throw std::runtime_error("netlink_nl_send: Unable to open socket");
}

if (sendmsg(nlfd, &msg, 0) < 0) {
free(nlmsg);
close(nlfd);
logger->error("netlink_nl_send: Unable to sendmsg");
throw std::runtime_error("netlink_nl_send: Unable to sendmsg");
}

/* read the reply message to check that there are no errors */
if (recvmsg(nlfd, &msg, 0) < 0) {
free(nlmsg);
close(nlfd);
logger->error("netlink_nl_send: Unable to recvmsg");
throw std::runtime_error("netlink_nl_send: Unable to recvmsg");
}

/* if there is an error return error code */
if (nlmsg->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(nlmsg);
free(nlmsg);
close(nlfd);
return err->error;
}

free(nlmsg);
close(nlfd);
return 0;
}

void Netlink::set_iface_status(const std::string &iface, IFACE_STATUS status) {
struct nlmsghdr *nlmsg = netlink_alloc();
struct nl_req *unr = (struct nl_req *)nlmsg;

int index = get_iface_index(iface);
if (index == -1) {
logger->error("set_iface_status: iface {0} does not exist", iface);
throw std::runtime_error("set_iface_status: iface does not exist");
}

unr->ifinfomsg.ifi_index = index;
unr->ifinfomsg.ifi_change |= IFF_UP;
if (status == IFACE_STATUS::UP)
unr->ifinfomsg.ifi_flags |= IFF_UP;
else if (status == IFACE_STATUS::DOWN)
unr->ifinfomsg.ifi_flags |= ~IFF_UP;

netlink_nl_send(nlmsg);
}

void Netlink::set_iface_mac(const std::string &iface, const std::string &mac) {
struct rtnl_link *link;
struct rtnl_link *old_link;
struct nl_sock *sk;
struct nl_cache *link_cache;

sk = nl_socket_alloc();
if (nl_connect(sk, NETLINK_ROUTE) < 0) {
logger->error("set_iface_mac: Unable to open socket");
throw std::runtime_error("set_iface_mac: Unable to open socket");
}

link = rtnl_link_alloc();
if (!link) {
nl_close(sk);
logger->error("set_iface_mac: Invalid link");
throw std::runtime_error("set_iface_mac: Invalid link");
}

rtnl_link_set_name(link, iface.c_str());

struct nl_addr* addr;
addr = nl_addr_build(AF_LLC, ether_aton(mac.c_str()), ETH_ALEN);
if (!addr) {
nl_close(sk);
logger->error("set_iface_mac: Invalid MAC address");
throw std::runtime_error("set_iface_mac: Invalid MAC address");
}
rtnl_link_set_addr(link, addr);

if (rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache) < 0) {
nl_close(sk);
logger->error("set_iface_mac: Unable to allocate cache");
throw std::runtime_error("set_iface_mac: Unable to allocate cache");
}

old_link = rtnl_link_get_by_name(link_cache, iface.c_str());
if (rtnl_link_change(sk, old_link, link, 0) < 0) {
nl_close(sk);
logger->error("set_iface_mac: Unable to change link");
throw std::runtime_error("set_iface_mac: Unable to change link");
}

rtnl_link_put(link);
nl_close(sk);
}

void Netlink::set_iface_ip(const std::string &iface, const std::string &ip, int prefix) {
struct nlmsghdr *nlmsg = netlink_ip_alloc();
struct nl_ipreq *uni = (struct nl_ipreq *)nlmsg;
struct rtattr *rta;
struct in_addr ia;

int index = get_iface_index(iface);
if (index == -1) {
logger->error("set_iface_ip: iface {0} does not exist", iface);
throw std::runtime_error("set_iface_ip: iface does not exist");
}

uni->ifaddrmsg.ifa_index = index;
uni->ifaddrmsg.ifa_prefixlen = prefix;

if (inet_pton(AF_INET, ip.c_str(), &ia) <= 0) {
free(nlmsg);
logger->error("set_iface_ip: Error in inet_pton");
throw std::runtime_error("set_iface_ip: Error in inet_pton");
}

rta = NLMSG_TAIL(nlmsg);
rta->rta_type = IFA_LOCAL;
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
memcpy(RTA_DATA(rta), &ia, sizeof(struct in_addr));
nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_ALIGN(rta->rta_len);

rta = NLMSG_TAIL(nlmsg);
rta->rta_type = IFA_ADDRESS;
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
memcpy(RTA_DATA(rta), &ia, sizeof(struct in_addr));
nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_ALIGN(rta->rta_len);

netlink_nl_send(nlmsg);
}

void Netlink::move_iface_into_ns(const std::string &iface, int fd) {
struct nlmsghdr *nlmsg = netlink_alloc();
struct nl_req *unr = (struct nl_req *)nlmsg;
struct rtattr *rta;

int index = get_iface_index(iface);
if (index == -1) {
logger->error("move_iface_into_ns: iface {0} does not exist", iface);
throw std::runtime_error("move_iface_into_ns: iface does not exist");
}

unr->ifinfomsg.ifi_index = index;
rta = NLMSG_TAIL(nlmsg);
rta->rta_type = IFLA_NET_NS_FD;
rta->rta_len = RTA_LENGTH(sizeof(int));

memcpy(RTA_DATA(rta), &fd, sizeof(pid_t));
nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_ALIGN(rta->rta_len);

netlink_nl_send(nlmsg);
}

} // namespace polycubed
} // namespace polycube

0 comments on commit ead77a8

Please sign in to comment.