xref: /aosp_15_r20/external/ltp/testcases/lib/tst_ns_ifmove.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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 <[email protected]>
5  * Written by Matus Marhefka <[email protected]>
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 
30 static struct {
31 	struct nlmsghdr nh;
32 	struct ifinfomsg ifi;
33 	char attrbuf[512];
34 } req;
35 
36 
get_intf_index_from_name(const char * intf_name)37 static 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 
main(int argc,char ** argv)55 int 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