blob: b2a651348a34e359ea2e5a100508f99d71eaecdb [file] [log] [blame]
Damjan Marion17fdae72017-11-30 20:56:37 +01001/*
2 *------------------------------------------------------------------
3 * Copyright (c) 2017 Cisco and/or its affiliates.
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
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <fcntl.h>
21#include <net/if.h>
22#include <linux/if_tun.h>
23#include <sys/ioctl.h>
24#include <linux/virtio_net.h>
25#include <linux/vhost.h>
26#include <sys/eventfd.h>
27
28#include <linux/netlink.h>
29#include <linux/rtnetlink.h>
30
31#include <vlib/vlib.h>
32#include <vlib/unix/unix.h>
33
34clib_error_t *
35vnet_netlink_set_if_attr (int ifindex, unsigned short rta_type, void *data,
36 int data_len)
37{
38 clib_error_t *err = 0;
39 int sock;
40 struct sockaddr_nl ra = { 0 };
41 struct
42 {
43 struct nlmsghdr nh;
44 struct ifinfomsg ifmsg;
45 char attrbuf[512];
46 } req;
47 struct rtattr *rta;
48
49 memset (&req, 0, sizeof (req));
50 if ((sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
51 {
52 err = clib_error_return_unix (0, "socket(AF_NETLINK)");
53 goto error;
54 }
55
56 ra.nl_family = AF_NETLINK;
57 ra.nl_pid = getpid ();
58
59 if ((bind (sock, (struct sockaddr *) &ra, sizeof (ra))) == -1)
60 return clib_error_return_unix (0, "bind");
61
62 req.nh.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifinfomsg));
63 req.nh.nlmsg_flags = NLM_F_REQUEST;
64 req.nh.nlmsg_type = RTM_SETLINK;
65 req.ifmsg.ifi_family = AF_UNSPEC;
66 req.ifmsg.ifi_index = ifindex;
67 req.ifmsg.ifi_change = 0xffffffff;
68 rta = (struct rtattr *) (((char *) &req) + NLMSG_ALIGN (req.nh.nlmsg_len));
69 rta->rta_type = rta_type;
70 rta->rta_len = RTA_LENGTH (data_len);
71 req.nh.nlmsg_len = NLMSG_ALIGN (req.nh.nlmsg_len) + RTA_LENGTH (data_len);
72 memcpy (RTA_DATA (rta), data, data_len);
73
74 if ((send (sock, &req, req.nh.nlmsg_len, 0)) == -1)
75 err = clib_error_return_unix (0, "send");
76
77error:
78 return err;
79}
80
81clib_error_t *
82vnet_netlink_set_if_mtu (int ifindex, int mtu)
83{
84 clib_error_t *err;
85
86 err = vnet_netlink_set_if_attr (ifindex, IFLA_MTU, &mtu, sizeof (int));
87 return err;
88}
89
90clib_error_t *
91vnet_netlink_set_if_namespace (int ifindex, char *net_ns)
92{
93 clib_error_t *err;
94 int ns_fd;
95 u8 *s;
96 s = format (0, "/var/run/netns/%s%c", net_ns, 0);
97 ns_fd = open ((char *) s, O_RDONLY);
98 vec_free (s);
99 if (ns_fd == -1)
100 return clib_error_return (0, "namespace '%s' doesn't exist", net_ns);
101
102 err =
103 vnet_netlink_set_if_attr (ifindex, IFLA_NET_NS_FD, &ns_fd, sizeof (int));
104 close (ns_fd);
105 return err;
106}
107
108/*
109 * fd.io coding-style-patch-verification: ON
110 *
111 * Local Variables:
112 * eval: (c-set-style "gnu")
113 * End:
114 */