TError TNlLink::AddVeth(const std::string &name, const std::string &hw, int mtu, int nsFd) { struct rtnl_link *veth, *peer; int ret; peer = rtnl_link_veth_alloc(); if (!peer) return TError(EError::Unknown, "Unable to allocate veth"); rtnl_link_set_name(peer, rtnl_link_get_name(Link)); veth = rtnl_link_veth_get_peer(peer); rtnl_link_set_name(veth, name.c_str()); if (nsFd >= 0) rtnl_link_set_ns_fd(veth, nsFd); if (mtu > 0) { rtnl_link_set_mtu(peer, mtu); rtnl_link_set_mtu(veth, mtu); } if (!hw.empty()) { TNlAddr addr; TError error = addr.Parse(AF_LLC, hw.c_str()); if (error) return error; rtnl_link_set_addr(veth, addr.Addr); } rtnl_link_set_flags(peer, IFF_UP); Dump("add", veth); rtnl_link_put(veth); Dump("add", peer); ret = rtnl_link_add(GetSock(), peer, NLM_F_CREATE | NLM_F_EXCL); if (ret < 0) { rtnl_link_put(peer); return Error(ret, "Cannot add veth"); } rtnl_link_put(peer); return Load(); }
/** * Create a new kernel veth device * @arg sock netlink socket * @arg name name of the veth device or NULL * @arg peer_name name of its peer or NULL * @arg pid pid of the process in the new netns * * Creates a new veth device pair in the kernel and move the peer * to the network namespace where the process is. If no name is * provided, the kernel will automatically pick a name of the * form "veth%d" (e.g. veth0, veth1, etc.) * * @return 0 on success or a negative error code */ int rtnl_link_veth_add(struct nl_sock *sock, const char *name, const char *peer_name, pid_t pid) { struct rtnl_link *link, *peer; int err = -NLE_NOMEM; if (!(link = rtnl_link_veth_alloc())) return -NLE_NOMEM; peer = rtnl_link_veth_get_peer(link); if (name && peer_name) { rtnl_link_set_name(link, name); rtnl_link_set_name(peer, peer_name); } rtnl_link_set_ns_pid(peer, pid); err = rtnl_link_add(sock, link, NLM_F_CREATE); rtnl_link_put(peer); rtnl_link_put(link); return err; }