1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "common/libs/net/netlink_client.h"
18 #include "common/libs/net/netlink_request.h"
19 #include "common/libs/net/network_interface.h"
20 #include "common/libs/net/network_interface_manager.h"
21
22 #include <linux/rtnetlink.h>
23 #include <net/if.h>
24 #include <iostream>
25 #include <string>
26
main(int argc,char * argv[])27 int main(int argc, char *argv[]) {
28 if (!((argc == 5 && std::string(argv[1]) == "vlan") ||
29 (argc == 4 && std::string(argv[1]) == "virt_wifi"))) {
30 std::cerr << "usages:\n";
31 std::cerr << " " << argv[0] << " vlan [ethA] [ethB] [index]\n";
32 std::cerr << " " << argv[0] << " virt_wifi [ethA] [ethB]\n";
33 return -1;
34 }
35 const char *const name = argv[2];
36 int32_t index = if_nametoindex(name);
37 if (index == 0) {
38 fprintf(stderr, "%s: invalid interface name '%s'\n", argv[2], name);
39 return -2;
40 }
41 const char *const new_name = argv[3];
42 auto factory = cvd::NetlinkClientFactory::Default();
43 std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE));
44
45 // http://maz-programmersdiary.blogspot.com/2011/09/netlink-sockets.html
46 cvd::NetlinkRequest link_add_request(RTM_NEWLINK, NLM_F_REQUEST|NLM_F_ACK|0x600);
47 link_add_request.Append(ifinfomsg {
48 .ifi_change = 0xFFFFFFFF,
49 });
50 link_add_request.AddString(IFLA_IFNAME, std::string(new_name));
51 link_add_request.AddInt(IFLA_LINK, index);
52
53 link_add_request.PushList(IFLA_LINKINFO);
54 link_add_request.AddString(IFLA_INFO_KIND, argv[1]);
55 link_add_request.PushList(IFLA_INFO_DATA);
56 if (std::string(argv[1]) == "vlan") {
57 uint16_t vlan_index = atoi(argv[4]);
58 link_add_request.AddInt(IFLA_VLAN_ID, vlan_index);
59 }
60 link_add_request.PopList();
61 link_add_request.PopList();
62
63 nl->Send(link_add_request);
64
65 cvd::NetlinkRequest bring_up_backing_request(RTM_SETLINK, NLM_F_REQUEST|NLM_F_ACK|0x600);
66 bring_up_backing_request.Append(ifinfomsg {
67 .ifi_index = index,
68 .ifi_flags = IFF_UP,
69 .ifi_change = 0xFFFFFFFF,
70 });
71
72 nl->Send(bring_up_backing_request);
73
74 return 0;
75 }
76