1// SPDX-License-Identifier: GPL-2.0-or-later 2/* Copyright (c) 2015 Red Hat, Inc. 3 * Copyright (c) Linux Test Project, 2015-2022 4 * Copyright (c) 2023 Petr Vorel <pvorel@suse.cz> 5 * Written by Matus Marhefka <mmarhefk@redhat.com> 6 */ 7 8/*\ 9 * [Description] 10 * 11 * Moves a network interface to the namespace of a process specified by a PID. 12 */ 13 14#include "config.h" 15 16#define TST_NO_DEFAULT_MAIN 17#include "tst_test.h" 18#include "tst_safe_macros.h" 19#include "tst_safe_net.h" 20 21#include <linux/if.h> 22#include <linux/rtnetlink.h> 23#include <net/ethernet.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27 28#ifdef HAVE_DECL_IFLA_NET_NS_PID 29 30static struct { 31 struct nlmsghdr nh; 32 struct ifinfomsg ifi; 33 char attrbuf[512]; 34} req; 35 36 37static int get_intf_index_from_name(const char *intf_name) 38{ 39 struct ifreq ifr; 40 int sock_fd; 41 42 memset(&ifr, 0, sizeof(ifr)); 43 strncpy(ifr.ifr_name, intf_name, sizeof(ifr.ifr_name) - 1); 44 ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0'; 45 46 sock_fd = SAFE_SOCKET(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 47 48 /* interface index */ 49 SAFE_IOCTL(sock_fd, SIOCGIFINDEX, &ifr); 50 SAFE_CLOSE(sock_fd); 51 52 return ifr.ifr_ifindex; 53} 54 55int main(int argc, char **argv) 56{ 57 struct rtattr *rta; 58 int intf_index, pid, rtnetlink_socket; 59 60 if (argc != 3) { 61 printf("tst_ns_ifmove <INTERFACE_NAME> <NAMESPACE_PID>\n"); 62 return 1; 63 } 64 65 intf_index = get_intf_index_from_name(argv[1]); 66 pid = atoi(argv[2]); 67 rtnetlink_socket = SAFE_SOCKET(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); 68 69 memset(&req, 0, sizeof(req)); 70 req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 71 req.nh.nlmsg_flags = NLM_F_REQUEST; 72 req.nh.nlmsg_type = RTM_NEWLINK; 73 req.ifi.ifi_family = AF_UNSPEC; 74 req.ifi.ifi_index = intf_index; 75 req.ifi.ifi_change = 0xffffffff; 76 rta = (struct rtattr *)(((char *) &req) + 77 NLMSG_ALIGN(req.nh.nlmsg_len)); 78 rta->rta_type = IFLA_NET_NS_PID; 79 rta->rta_len = RTA_LENGTH(sizeof(int)); 80 req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + 81 RTA_LENGTH(sizeof(pid)); 82 memcpy(RTA_DATA(rta), &pid, sizeof(pid)); 83 84 SAFE_SEND(1, rtnetlink_socket, &req, req.nh.nlmsg_len, 0); 85 SAFE_CLOSE(rtnetlink_socket); 86 87 return 0; 88} 89 90#else 91 TST_TEST_TCONF("IFLA_NET_NS_PID not defined in linux/if_link.h"); 92#endif 93