blob: 3fd3e13bf770aa010382323580ae8e91d732db46 [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>
Damjan Marion17fdae72017-11-30 20:56:37 +010022
Tom Jones9bf4f8f2024-01-29 15:12:34 +000023#ifdef __linux__
Damjan Marion17fdae72017-11-30 20:56:37 +010024#include <linux/netlink.h>
25#include <linux/rtnetlink.h>
Tom Jones9bf4f8f2024-01-29 15:12:34 +000026#elif __FreeBSD__
27#include <netlink/netlink.h>
28#include <netlink/netlink_route.h>
29#endif
Damjan Marion17fdae72017-11-30 20:56:37 +010030
31#include <vlib/vlib.h>
32#include <vlib/unix/unix.h>
Damjan Marion2df39092017-12-04 20:03:37 +010033#include <vnet/devices/netlink.h>
Damjan Marion17fdae72017-11-30 20:56:37 +010034
Damjan Marion91c6ef72017-12-01 13:34:24 +010035typedef struct
36{
37 u8 *data;
38} vnet_netlink_msg_t;
39
Damjan Marion2df39092017-12-04 20:03:37 +010040static void
Damjan Marion91c6ef72017-12-01 13:34:24 +010041vnet_netlink_msg_init (vnet_netlink_msg_t * m, u16 type, u16 flags,
42 void *msg_data, int msg_len)
43{
44 struct nlmsghdr *nh;
45 u8 *p;
Dave Barachb7b92992018-10-17 10:38:51 -040046 clib_memset (m, 0, sizeof (vnet_netlink_msg_t));
Damjan Marion2df39092017-12-04 20:03:37 +010047 vec_add2 (m->data, p, NLMSG_SPACE (msg_len));
Damjan Marion91c6ef72017-12-01 13:34:24 +010048 ASSERT (m->data == p);
49
50 nh = (struct nlmsghdr *) p;
Damjan Marion2df39092017-12-04 20:03:37 +010051 nh->nlmsg_flags = flags | NLM_F_ACK;
Damjan Marion91c6ef72017-12-01 13:34:24 +010052 nh->nlmsg_type = type;
53 clib_memcpy (m->data + sizeof (struct nlmsghdr), msg_data, msg_len);
54}
55
56static void
57vnet_netlink_msg_add_rtattr (vnet_netlink_msg_t * m, u16 rta_type,
58 void *rta_data, int rta_data_len)
59{
60 struct rtattr *rta;
61 u8 *p;
62
Damjan Marion2df39092017-12-04 20:03:37 +010063 vec_add2 (m->data, p, RTA_SPACE (rta_data_len));
Damjan Marion91c6ef72017-12-01 13:34:24 +010064 rta = (struct rtattr *) p;
65 rta->rta_type = rta_type;
66 rta->rta_len = RTA_LENGTH (rta_data_len);
67 clib_memcpy (RTA_DATA (rta), rta_data, rta_data_len);
68}
69
70static clib_error_t *
Aloys Augustine39376e2021-03-29 22:08:09 +020071vnet_netlink_msg_send (vnet_netlink_msg_t *m, vnet_netlink_msg_t **replies)
Damjan Marion17fdae72017-11-30 20:56:37 +010072{
73 clib_error_t *err = 0;
Damjan Marion17fdae72017-11-30 20:56:37 +010074 struct sockaddr_nl ra = { 0 };
Damjan Marion2df39092017-12-04 20:03:37 +010075 int len, sock;
Damjan Marion91c6ef72017-12-01 13:34:24 +010076 struct nlmsghdr *nh = (struct nlmsghdr *) m->data;
77 nh->nlmsg_len = vec_len (m->data);
Damjan Marion2df39092017-12-04 20:03:37 +010078 char buf[4096];
Damjan Marion17fdae72017-11-30 20:56:37 +010079
Damjan Marion17fdae72017-11-30 20:56:37 +010080 if ((sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
Stevenf953dfc2017-11-30 16:56:54 -080081 return clib_error_return_unix (0, "socket(AF_NETLINK)");
Damjan Marion17fdae72017-11-30 20:56:37 +010082
83 ra.nl_family = AF_NETLINK;
Jon Loeliger258fefd2018-03-02 13:05:12 -060084 ra.nl_pid = 0;
Damjan Marion17fdae72017-11-30 20:56:37 +010085
86 if ((bind (sock, (struct sockaddr *) &ra, sizeof (ra))) == -1)
Stevenf953dfc2017-11-30 16:56:54 -080087 {
88 err = clib_error_return_unix (0, "bind");
Damjan Marion2df39092017-12-04 20:03:37 +010089 goto done;
Stevenf953dfc2017-11-30 16:56:54 -080090 }
Damjan Marion17fdae72017-11-30 20:56:37 +010091
Damjan Marion91c6ef72017-12-01 13:34:24 +010092 if ((send (sock, m->data, vec_len (m->data), 0)) == -1)
Damjan Marion17fdae72017-11-30 20:56:37 +010093 err = clib_error_return_unix (0, "send");
94
Damjan Marion2df39092017-12-04 20:03:37 +010095 if ((len = recv (sock, buf, sizeof (buf), 0)) == -1)
96 err = clib_error_return_unix (0, "recv");
97
98 for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);
99 nh = NLMSG_NEXT (nh, len))
100 {
101 if (nh->nlmsg_type == NLMSG_DONE)
102 goto done;
103
104 if (nh->nlmsg_type == NLMSG_ERROR)
105 {
106 struct nlmsgerr *e = (struct nlmsgerr *) NLMSG_DATA (nh);
107 if (e->error)
108 err = clib_error_return (0, "netlink error %d", e->error);
109 goto done;
110 }
Aloys Augustine39376e2021-03-29 22:08:09 +0200111
112 if (replies)
113 {
114 vnet_netlink_msg_t msg = { NULL };
115 u8 *p;
116 vec_add2 (msg.data, p, nh->nlmsg_len);
117 clib_memcpy (p, nh, nh->nlmsg_len);
118 vec_add1 (*replies, msg);
119 }
Damjan Marion2df39092017-12-04 20:03:37 +0100120 }
121
122done:
Stevenf953dfc2017-11-30 16:56:54 -0800123 close (sock);
Damjan Marion91c6ef72017-12-01 13:34:24 +0100124 vec_free (m->data);
Damjan Marion17fdae72017-11-30 20:56:37 +0100125 return err;
126}
127
128clib_error_t *
Damjan Marion2df39092017-12-04 20:03:37 +0100129vnet_netlink_set_link_name (int ifindex, char *new_ifname)
Damjan Marion17fdae72017-11-30 20:56:37 +0100130{
Damjan Marion91c6ef72017-12-01 13:34:24 +0100131 vnet_netlink_msg_t m;
132 struct ifinfomsg ifmsg = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100133 clib_error_t *err = 0;
Damjan Marion17fdae72017-11-30 20:56:37 +0100134
Damjan Marion91c6ef72017-12-01 13:34:24 +0100135 ifmsg.ifi_index = ifindex;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100136 vnet_netlink_msg_init (&m, RTM_SETLINK, NLM_F_REQUEST,
137 &ifmsg, sizeof (struct ifinfomsg));
138
Damjan Marion2df39092017-12-04 20:03:37 +0100139 vnet_netlink_msg_add_rtattr (&m, IFLA_IFNAME, new_ifname,
140 strlen (new_ifname) + 1);
Damjan Marion91c6ef72017-12-01 13:34:24 +0100141
Aloys Augustine39376e2021-03-29 22:08:09 +0200142 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100143 if (err)
144 err = clib_error_return (0, "set link name %U", format_clib_error, err);
145 return err;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100146}
147
148clib_error_t *
Damjan Marion2df39092017-12-04 20:03:37 +0100149vnet_netlink_set_link_netns (int ifindex, int netns_fd, char *new_ifname)
Damjan Marion91c6ef72017-12-01 13:34:24 +0100150{
151 vnet_netlink_msg_t m;
152 struct ifinfomsg ifmsg = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100153 clib_error_t *err = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100154
Damjan Marion91c6ef72017-12-01 13:34:24 +0100155 ifmsg.ifi_index = ifindex;
Damjan Marion2df39092017-12-04 20:03:37 +0100156 vnet_netlink_msg_init (&m, RTM_SETLINK, NLM_F_REQUEST,
157 &ifmsg, sizeof (struct ifinfomsg));
158
159 vnet_netlink_msg_add_rtattr (&m, IFLA_NET_NS_FD, &netns_fd, sizeof (int));
160 if (new_ifname)
161 vnet_netlink_msg_add_rtattr (&m, IFLA_IFNAME, new_ifname,
162 strlen (new_ifname) + 1);
163
Aloys Augustine39376e2021-03-29 22:08:09 +0200164 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100165 if (err)
166 err = clib_error_return (0, "set link netns %U", format_clib_error, err);
167 return err;
Damjan Marion2df39092017-12-04 20:03:37 +0100168}
169
170clib_error_t *
171vnet_netlink_set_link_master (int ifindex, char *master_ifname)
172{
173 vnet_netlink_msg_t m;
174 struct ifinfomsg ifmsg = { 0 };
175 int i;
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100176 clib_error_t *err = 0;
Damjan Marion2df39092017-12-04 20:03:37 +0100177
178 ifmsg.ifi_index = ifindex;
179
180 if ((i = if_nametoindex (master_ifname)) == 0)
181 clib_error_return_unix (0, "unknown master interface '%s'",
182 master_ifname);
183
184 vnet_netlink_msg_init (&m, RTM_SETLINK, NLM_F_REQUEST,
185 &ifmsg, sizeof (struct ifinfomsg));
186 vnet_netlink_msg_add_rtattr (&m, IFLA_MASTER, &i, sizeof (int));
Aloys Augustine39376e2021-03-29 22:08:09 +0200187 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100188 if (err)
189 err = clib_error_return (0, "set link master %U", format_clib_error, err);
190 return err;
Damjan Marion2df39092017-12-04 20:03:37 +0100191}
192
193clib_error_t *
194vnet_netlink_set_link_addr (int ifindex, u8 * mac)
195{
196 vnet_netlink_msg_t m;
197 struct ifinfomsg ifmsg = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100198 clib_error_t *err = 0;
Damjan Marion2df39092017-12-04 20:03:37 +0100199
200 ifmsg.ifi_index = ifindex;
201
202 vnet_netlink_msg_init (&m, RTM_SETLINK, NLM_F_REQUEST,
203 &ifmsg, sizeof (struct ifinfomsg));
204 vnet_netlink_msg_add_rtattr (&m, IFLA_ADDRESS, mac, 6);
Aloys Augustine39376e2021-03-29 22:08:09 +0200205 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100206 if (err)
207 err = clib_error_return (0, "set link addr %U", format_clib_error, err);
208 return err;
Damjan Marion2df39092017-12-04 20:03:37 +0100209}
210
211clib_error_t *
212vnet_netlink_set_link_state (int ifindex, int up)
213{
214 vnet_netlink_msg_t m;
215 struct ifinfomsg ifmsg = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100216 clib_error_t *err = 0;
Damjan Marion2df39092017-12-04 20:03:37 +0100217
Matthew Smith81284162020-04-24 13:43:12 -0500218 ifmsg.ifi_flags = ((up) ? IFF_UP : 0);
Damjan Marion2df39092017-12-04 20:03:37 +0100219 ifmsg.ifi_change = IFF_UP;
220 ifmsg.ifi_index = ifindex;
221
222 vnet_netlink_msg_init (&m, RTM_SETLINK, NLM_F_REQUEST,
223 &ifmsg, sizeof (struct ifinfomsg));
Aloys Augustine39376e2021-03-29 22:08:09 +0200224 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100225 if (err)
226 err = clib_error_return (0, "set link state %U", format_clib_error, err);
227 return err;
Damjan Marion2df39092017-12-04 20:03:37 +0100228}
229
230clib_error_t *
Aloys Augustine39376e2021-03-29 22:08:09 +0200231vnet_netlink_get_link_mtu (int ifindex, u32 *mtu)
232{
233 vnet_netlink_msg_t m, *msg;
234 struct ifinfomsg ifmsg = { 0 };
235 struct nlattr *attr;
236 clib_error_t *err = 0;
237 vnet_netlink_msg_t *replies = NULL;
238 int len = 0, offset = 0;
239 u32 msg_mtu;
240
241 ifmsg.ifi_index = ifindex;
242
243 vnet_netlink_msg_init (&m, RTM_GETLINK, NLM_F_REQUEST, &ifmsg,
244 sizeof (struct ifinfomsg));
245 // vnet_netlink_msg_add_rtattr (&m, IFLA_MTU, &mtu, sizeof (int));
246 err = vnet_netlink_msg_send (&m, &replies);
247 if (err)
248 {
249 err = clib_error_return (0, "get link mtu %U", format_clib_error, err);
250 goto done;
251 }
252
253 if (vec_len (replies) != 1)
254 {
255 err = clib_error_return (0, "got %d != 1 netlink reply msg",
256 vec_len (replies));
257 goto done;
258 }
259
260 struct nlmsghdr *nh = (struct nlmsghdr *) replies[0].data;
261 if (nh->nlmsg_type != RTM_NEWLINK)
262 {
263 err = clib_error_return (
264 0, "netlink reply has wrong type: %d != RTM_NEWLINK", nh->nlmsg_type);
265 goto done;
266 }
267
268 offset = NLMSG_HDRLEN + NLMSG_ALIGN (sizeof (struct ifinfomsg));
269 attr = (struct nlattr *) ((u8 *) nh + offset);
270 len = nh->nlmsg_len - offset;
271
272 do
273 {
274 if ((attr->nla_type & NLA_TYPE_MASK) == IFLA_MTU)
275 {
276 msg_mtu = *(u32 *) ((u8 *) attr + NLA_HDRLEN);
277 if (attr->nla_type & NLA_F_NET_BYTEORDER)
278 *mtu = clib_net_to_host_u32 (msg_mtu);
279 else
280 *mtu = msg_mtu;
Aloys Augustine39376e2021-03-29 22:08:09 +0200281 goto done;
282 }
283 offset = NLA_ALIGN (attr->nla_len);
284 len -= offset;
285 attr = (struct nlattr *) ((u8 *) attr + offset);
286 }
287 while (len > sizeof (struct nlattr));
288
289 /* not found */
290 err = clib_error_return (0, "mtu not found in netlink message");
291
292done:
293 vec_foreach (msg, replies)
294 {
295 vec_free (msg->data);
296 }
297 vec_free (replies);
298
299 return err;
300}
301
302clib_error_t *
Damjan Marion2df39092017-12-04 20:03:37 +0100303vnet_netlink_set_link_mtu (int ifindex, int mtu)
304{
305 vnet_netlink_msg_t m;
306 struct ifinfomsg ifmsg = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100307 clib_error_t *err = 0;
Damjan Marion2df39092017-12-04 20:03:37 +0100308
309 ifmsg.ifi_index = ifindex;
310
Damjan Marion91c6ef72017-12-01 13:34:24 +0100311 vnet_netlink_msg_init (&m, RTM_SETLINK, NLM_F_REQUEST,
312 &ifmsg, sizeof (struct ifinfomsg));
313 vnet_netlink_msg_add_rtattr (&m, IFLA_MTU, &mtu, sizeof (int));
Aloys Augustine39376e2021-03-29 22:08:09 +0200314 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100315 if (err)
316 err = clib_error_return (0, "set link mtu %U", format_clib_error, err);
317 return err;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100318}
319
320clib_error_t *
321vnet_netlink_add_ip4_addr (int ifindex, void *addr, int pfx_len)
322{
323 vnet_netlink_msg_t m;
324 struct ifaddrmsg ifa = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100325 clib_error_t *err = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100326
327 ifa.ifa_family = AF_INET;
328 ifa.ifa_prefixlen = pfx_len;
329 ifa.ifa_index = ifindex;
330
331 vnet_netlink_msg_init (&m, RTM_NEWADDR,
Dave Barach7e869472020-03-13 08:32:28 -0400332 NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
Damjan Marion91c6ef72017-12-01 13:34:24 +0100333 &ifa, sizeof (struct ifaddrmsg));
334
335 vnet_netlink_msg_add_rtattr (&m, IFA_LOCAL, addr, 4);
336 vnet_netlink_msg_add_rtattr (&m, IFA_ADDRESS, addr, 4);
Aloys Augustine39376e2021-03-29 22:08:09 +0200337 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100338 if (err)
339 err = clib_error_return (0, "add ip4 addr %U", format_clib_error, err);
340 return err;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100341}
342
343clib_error_t *
344vnet_netlink_add_ip6_addr (int ifindex, void *addr, int pfx_len)
345{
346 vnet_netlink_msg_t m;
347 struct ifaddrmsg ifa = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100348 clib_error_t *err = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100349
350 ifa.ifa_family = AF_INET6;
351 ifa.ifa_prefixlen = pfx_len;
352 ifa.ifa_index = ifindex;
353
354 vnet_netlink_msg_init (&m, RTM_NEWADDR,
Dave Barach7e869472020-03-13 08:32:28 -0400355 NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
Damjan Marion91c6ef72017-12-01 13:34:24 +0100356 &ifa, sizeof (struct ifaddrmsg));
357
358 vnet_netlink_msg_add_rtattr (&m, IFA_LOCAL, addr, 16);
359 vnet_netlink_msg_add_rtattr (&m, IFA_ADDRESS, addr, 16);
Aloys Augustine39376e2021-03-29 22:08:09 +0200360 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100361 if (err)
362 err = clib_error_return (0, "add ip6 addr %U", format_clib_error, err);
363 return err;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100364}
365
Damjan Marion7866c452018-01-18 13:35:11 +0100366clib_error_t *
367vnet_netlink_add_ip4_route (void *dst, u8 dst_len, void *gw)
368{
369 vnet_netlink_msg_t m;
370 struct rtmsg rtm = { 0 };
371 u8 dflt[4] = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100372 clib_error_t *err = 0;
Damjan Marion7866c452018-01-18 13:35:11 +0100373
374 rtm.rtm_family = AF_INET;
375 rtm.rtm_table = RT_TABLE_MAIN;
376 rtm.rtm_type = RTN_UNICAST;
377 rtm.rtm_dst_len = dst_len;
378
379 vnet_netlink_msg_init (&m, RTM_NEWROUTE,
Dave Barach7e869472020-03-13 08:32:28 -0400380 NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
Damjan Marion7866c452018-01-18 13:35:11 +0100381 &rtm, sizeof (struct rtmsg));
382
383 vnet_netlink_msg_add_rtattr (&m, RTA_GATEWAY, gw, 4);
384 vnet_netlink_msg_add_rtattr (&m, RTA_DST, dst ? dst : dflt, 4);
Aloys Augustine39376e2021-03-29 22:08:09 +0200385 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100386 if (err)
387 err = clib_error_return (0, "add ip4 route %U", format_clib_error, err);
388 return err;
Damjan Marion7866c452018-01-18 13:35:11 +0100389}
390
391clib_error_t *
392vnet_netlink_add_ip6_route (void *dst, u8 dst_len, void *gw)
393{
394 vnet_netlink_msg_t m;
395 struct rtmsg rtm = { 0 };
396 u8 dflt[16] = { 0 };
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100397 clib_error_t *err = 0;
Damjan Marion7866c452018-01-18 13:35:11 +0100398
399 rtm.rtm_family = AF_INET6;
400 rtm.rtm_table = RT_TABLE_MAIN;
401 rtm.rtm_type = RTN_UNICAST;
402 rtm.rtm_dst_len = dst_len;
403
404 vnet_netlink_msg_init (&m, RTM_NEWROUTE,
Dave Barach7e869472020-03-13 08:32:28 -0400405 NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
Damjan Marion7866c452018-01-18 13:35:11 +0100406 &rtm, sizeof (struct rtmsg));
407
408 vnet_netlink_msg_add_rtattr (&m, RTA_GATEWAY, gw, 16);
409 vnet_netlink_msg_add_rtattr (&m, RTA_DST, dst ? dst : dflt, 16);
Aloys Augustine39376e2021-03-29 22:08:09 +0200410 err = vnet_netlink_msg_send (&m, NULL);
Mohsin Kazmib9f1f152020-01-31 12:37:44 +0100411 if (err)
412 err = clib_error_return (0, "add ip6 route %U", format_clib_error, err);
413 return err;
Damjan Marion7866c452018-01-18 13:35:11 +0100414}
415
Pim van Pelt1705a6b2021-09-09 17:53:09 +0000416clib_error_t *
417vnet_netlink_del_ip4_addr (int ifindex, void *addr, int pfx_len)
418{
419 vnet_netlink_msg_t m;
420 struct ifaddrmsg ifa = { 0 };
421 clib_error_t *err = 0;
422
423 ifa.ifa_family = AF_INET;
424 ifa.ifa_prefixlen = pfx_len;
425 ifa.ifa_index = ifindex;
426
427 vnet_netlink_msg_init (&m, RTM_DELADDR, NLM_F_REQUEST, &ifa,
428 sizeof (struct ifaddrmsg));
429
430 vnet_netlink_msg_add_rtattr (&m, IFA_LOCAL, addr, 4);
431 vnet_netlink_msg_add_rtattr (&m, IFA_ADDRESS, addr, 4);
432 err = vnet_netlink_msg_send (&m, NULL);
433 if (err)
434 err = clib_error_return (0, "del ip4 addr %U", format_clib_error, err);
435 return err;
436}
437
438clib_error_t *
439vnet_netlink_del_ip6_addr (int ifindex, void *addr, int pfx_len)
440{
441 vnet_netlink_msg_t m;
442 struct ifaddrmsg ifa = { 0 };
443 clib_error_t *err = 0;
444
445 ifa.ifa_family = AF_INET6;
446 ifa.ifa_prefixlen = pfx_len;
447 ifa.ifa_index = ifindex;
448
449 vnet_netlink_msg_init (&m, RTM_DELADDR, NLM_F_REQUEST, &ifa,
450 sizeof (struct ifaddrmsg));
451
452 vnet_netlink_msg_add_rtattr (&m, IFA_LOCAL, addr, 16);
453 vnet_netlink_msg_add_rtattr (&m, IFA_ADDRESS, addr, 16);
454 err = vnet_netlink_msg_send (&m, NULL);
455 if (err)
456 err = clib_error_return (0, "del ip6 addr %U", format_clib_error, err);
457 return err;
458}
459
Damjan Marion17fdae72017-11-30 20:56:37 +0100460/*
461 * fd.io coding-style-patch-verification: ON
462 *
463 * Local Variables:
464 * eval: (c-set-style "gnu")
465 * End:
466 */