1f08c3bdfSopenharmony_ci/* Copyright (c) 2015 Red Hat, Inc. 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * This program is free software: you can redistribute it and/or modify 4f08c3bdfSopenharmony_ci * it under the terms of version 2 the GNU General Public License as 5f08c3bdfSopenharmony_ci * published by the Free Software Foundation. 6f08c3bdfSopenharmony_ci * 7f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 8f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 9f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10f08c3bdfSopenharmony_ci * GNU General Public License for more details. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 13f08c3bdfSopenharmony_ci * along with this program. If not, see <http://www.gnu.org/licenses/>. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * Written by Matus Marhefka <mmarhefk@redhat.com> 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci *********************************************************************** 18f08c3bdfSopenharmony_ci * Moves a network interface to the namespace of a process specified by a PID. 19f08c3bdfSopenharmony_ci * 20f08c3bdfSopenharmony_ci */ 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci#define _GNU_SOURCE 23f08c3bdfSopenharmony_ci#include <stdlib.h> 24f08c3bdfSopenharmony_ci#include <string.h> 25f08c3bdfSopenharmony_ci#include <errno.h> 26f08c3bdfSopenharmony_ci#include <unistd.h> 27f08c3bdfSopenharmony_ci#include <asm/types.h> 28f08c3bdfSopenharmony_ci#include <sys/socket.h> 29f08c3bdfSopenharmony_ci#include <linux/rtnetlink.h> 30f08c3bdfSopenharmony_ci#include <sys/ioctl.h> 31f08c3bdfSopenharmony_ci#include <linux/if.h> 32f08c3bdfSopenharmony_ci#include <net/ethernet.h> 33f08c3bdfSopenharmony_ci#include <arpa/inet.h> 34f08c3bdfSopenharmony_ci#include "test.h" 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#include "config.h" 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_cichar *TCID = "ns_ifmove"; 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci#if HAVE_DECL_IFLA_NET_NS_PID 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_cistruct { 43f08c3bdfSopenharmony_ci struct nlmsghdr nh; 44f08c3bdfSopenharmony_ci struct ifinfomsg ifi; 45f08c3bdfSopenharmony_ci char attrbuf[512]; 46f08c3bdfSopenharmony_ci} req; 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ciint get_intf_index_from_name(const char *intf_name) 50f08c3bdfSopenharmony_ci{ 51f08c3bdfSopenharmony_ci struct ifreq ifr; 52f08c3bdfSopenharmony_ci int sock_fd; 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ci memset(&ifr, 0, sizeof(ifr)); 55f08c3bdfSopenharmony_ci strncpy(ifr.ifr_name, intf_name, sizeof(ifr.ifr_name) - 1); 56f08c3bdfSopenharmony_ci ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0'; 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 59f08c3bdfSopenharmony_ci if (sock_fd == -1) { 60f08c3bdfSopenharmony_ci tst_resm(TINFO | TERRNO, "socket"); 61f08c3bdfSopenharmony_ci return -1; 62f08c3bdfSopenharmony_ci } 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci /* gets interface index */ 65f08c3bdfSopenharmony_ci if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) == -1) { 66f08c3bdfSopenharmony_ci tst_resm(TINFO | TERRNO, "ioctl"); 67f08c3bdfSopenharmony_ci close(sock_fd); 68f08c3bdfSopenharmony_ci return -1; 69f08c3bdfSopenharmony_ci } 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci close(sock_fd); 72f08c3bdfSopenharmony_ci return ifr.ifr_ifindex; 73f08c3bdfSopenharmony_ci} 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci/* 76f08c3bdfSopenharmony_ci * ./ns_ifmove <INTERFACE_NAME> <NAMESPACE_PID> 77f08c3bdfSopenharmony_ci */ 78f08c3bdfSopenharmony_ciint main(int argc, char **argv) 79f08c3bdfSopenharmony_ci{ 80f08c3bdfSopenharmony_ci struct rtattr *rta; 81f08c3bdfSopenharmony_ci int intf_index, pid, rtnetlink_socket; 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci if (argc != 3) { 84f08c3bdfSopenharmony_ci tst_resm(TINFO, "%s <INTERFACE_NAME> <NAMESPACE_PID>", 85f08c3bdfSopenharmony_ci argv[0]); 86f08c3bdfSopenharmony_ci return 1; 87f08c3bdfSopenharmony_ci } 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci intf_index = get_intf_index_from_name(argv[1]); 90f08c3bdfSopenharmony_ci if (intf_index == -1) { 91f08c3bdfSopenharmony_ci tst_resm(TINFO , "unable to get interface index"); 92f08c3bdfSopenharmony_ci return 1; 93f08c3bdfSopenharmony_ci } 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci pid = atoi(argv[2]); 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci rtnetlink_socket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); 98f08c3bdfSopenharmony_ci if (rtnetlink_socket == -1) { 99f08c3bdfSopenharmony_ci tst_resm(TINFO | TERRNO, "socket"); 100f08c3bdfSopenharmony_ci return 1; 101f08c3bdfSopenharmony_ci } 102f08c3bdfSopenharmony_ci 103f08c3bdfSopenharmony_ci memset(&req, 0, sizeof(req)); 104f08c3bdfSopenharmony_ci req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 105f08c3bdfSopenharmony_ci req.nh.nlmsg_flags = NLM_F_REQUEST; 106f08c3bdfSopenharmony_ci req.nh.nlmsg_type = RTM_NEWLINK; 107f08c3bdfSopenharmony_ci req.ifi.ifi_family = AF_UNSPEC; 108f08c3bdfSopenharmony_ci req.ifi.ifi_index = intf_index; 109f08c3bdfSopenharmony_ci req.ifi.ifi_change = 0xffffffff; 110f08c3bdfSopenharmony_ci rta = (struct rtattr *)(((char *) &req) + 111f08c3bdfSopenharmony_ci NLMSG_ALIGN(req.nh.nlmsg_len)); 112f08c3bdfSopenharmony_ci rta->rta_type = IFLA_NET_NS_PID; 113f08c3bdfSopenharmony_ci rta->rta_len = RTA_LENGTH(sizeof(int)); 114f08c3bdfSopenharmony_ci req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + 115f08c3bdfSopenharmony_ci RTA_LENGTH(sizeof(pid)); 116f08c3bdfSopenharmony_ci memcpy(RTA_DATA(rta), &pid, sizeof(pid)); 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci if (send(rtnetlink_socket, &req, req.nh.nlmsg_len, 0) == -1) { 119f08c3bdfSopenharmony_ci tst_resm(TINFO | TERRNO, "send"); 120f08c3bdfSopenharmony_ci return 1; 121f08c3bdfSopenharmony_ci } 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci close(rtnetlink_socket); 124f08c3bdfSopenharmony_ci return 0; 125f08c3bdfSopenharmony_ci} 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci#else 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ciint main(void) 130f08c3bdfSopenharmony_ci{ 131f08c3bdfSopenharmony_ci tst_brkm(TCONF, NULL, "IFLA_NET_NS_PID not defined in linux/if_link.h"); 132f08c3bdfSopenharmony_ci} 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci#endif 135