]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/rtnl-message.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / rtnl-message.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
89489ef7
TG
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Tom Gundersen <teg@jklm.no>
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include <netinet/in.h>
30746d60 22#include <linux/if_addrlabel.h>
89489ef7
TG
23#include <stdbool.h>
24#include <unistd.h>
25
07630cea
LP
26#include "sd-netlink.h"
27
f97b34a6 28#include "format-util.h"
89489ef7 29#include "missing.h"
89489ef7
TG
30#include "netlink-internal.h"
31#include "netlink-types.h"
07630cea
LP
32#include "netlink-util.h"
33#include "refcnt.h"
34#include "socket-util.h"
35#include "util.h"
89489ef7
TG
36
37int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
38 struct rtmsg *rtm;
39
40 assert_return(m, -EINVAL);
41 assert_return(m->hdr, -EINVAL);
42 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
43
44 rtm = NLMSG_DATA(m->hdr);
45
46 if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
47 (rtm->rtm_family == AF_INET6 && prefixlen > 128))
48 return -ERANGE;
49
50 rtm->rtm_dst_len = prefixlen;
51
52 return 0;
53}
54
55int sd_rtnl_message_route_set_src_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
56 struct rtmsg *rtm;
57
58 assert_return(m, -EINVAL);
59 assert_return(m->hdr, -EINVAL);
60 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
61
62 rtm = NLMSG_DATA(m->hdr);
63
64 if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
65 (rtm->rtm_family == AF_INET6 && prefixlen > 128))
66 return -ERANGE;
67
68 rtm->rtm_src_len = prefixlen;
69
70 return 0;
71}
72
73int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope) {
74 struct rtmsg *rtm;
75
76 assert_return(m, -EINVAL);
77 assert_return(m->hdr, -EINVAL);
78 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
79
80 rtm = NLMSG_DATA(m->hdr);
81
82 rtm->rtm_scope = scope;
83
84 return 0;
85}
86
6b9e85a7
TG
87int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags) {
88 struct rtmsg *rtm;
89
90 assert_return(m, -EINVAL);
91 assert_return(m->hdr, -EINVAL);
92 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
93
94 rtm = NLMSG_DATA(m->hdr);
95
96 rtm->rtm_flags = flags;
97
98 return 0;
99}
100
101int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags) {
102 struct rtmsg *rtm;
103
104 assert_return(m, -EINVAL);
105 assert_return(m->hdr, -EINVAL);
106 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
107 assert_return(flags, -EINVAL);
108
109 rtm = NLMSG_DATA(m->hdr);
110
111 *flags = rtm->rtm_flags;
112
113 return 0;
114}
115
ec1bb279
SS
116int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table) {
117 struct rtmsg *rtm;
118
119 assert_return(m, -EINVAL);
120 assert_return(m->hdr, -EINVAL);
121 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
122
123 rtm = NLMSG_DATA(m->hdr);
124
125 rtm->rtm_table = table;
126
127 return 0;
128}
129
89489ef7
TG
130int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) {
131 struct rtmsg *rtm;
132
133 assert_return(m, -EINVAL);
134 assert_return(m->hdr, -EINVAL);
135 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
136 assert_return(family, -EINVAL);
137
138 rtm = NLMSG_DATA(m->hdr);
139
140 *family = rtm->rtm_family;
141
142 return 0;
143}
144
ec1bb279
SS
145int sd_rtnl_message_route_set_family(sd_netlink_message *m, int family) {
146 struct rtmsg *rtm;
147
148 assert_return(m, -EINVAL);
149 assert_return(m->hdr, -EINVAL);
150 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
151
152 rtm = NLMSG_DATA(m->hdr);
153
154 rtm->rtm_family = family;
155
156 return 0;
157}
158
983226f3
SS
159int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type) {
160 struct rtmsg *rtm;
161
162 assert_return(m, -EINVAL);
163 assert_return(m->hdr, -EINVAL);
164 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
165 assert_return(type, -EINVAL);
166
167 rtm = NLMSG_DATA(m->hdr);
168
169 *type = rtm->rtm_type;
170
171 return 0;
172}
173
174int sd_rtnl_message_route_set_type(sd_netlink_message *m, unsigned char type) {
175 struct rtmsg *rtm;
176
177 assert_return(m, -EINVAL);
178 assert_return(m->hdr, -EINVAL);
179 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
180
181 rtm = NLMSG_DATA(m->hdr);
182
183 rtm->rtm_type = type;
184
185 return 0;
186}
187
ad70f789
TG
188int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol) {
189 struct rtmsg *rtm;
190
191 assert_return(m, -EINVAL);
192 assert_return(m->hdr, -EINVAL);
193 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
194 assert_return(protocol, -EINVAL);
195
196 rtm = NLMSG_DATA(m->hdr);
197
198 *protocol = rtm->rtm_protocol;
199
200 return 0;
201}
202
203int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope) {
204 struct rtmsg *rtm;
205
206 assert_return(m, -EINVAL);
207 assert_return(m->hdr, -EINVAL);
208 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
209 assert_return(scope, -EINVAL);
210
211 rtm = NLMSG_DATA(m->hdr);
212
213 *scope = rtm->rtm_scope;
214
215 return 0;
216}
217
218int sd_rtnl_message_route_get_tos(sd_netlink_message *m, unsigned char *tos) {
219 struct rtmsg *rtm;
220
221 assert_return(m, -EINVAL);
222 assert_return(m->hdr, -EINVAL);
223 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
224 assert_return(tos, -EINVAL);
225
226 rtm = NLMSG_DATA(m->hdr);
227
228 *tos = rtm->rtm_tos;
229
230 return 0;
231}
232
233int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table) {
234 struct rtmsg *rtm;
235
236 assert_return(m, -EINVAL);
237 assert_return(m->hdr, -EINVAL);
238 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
239 assert_return(table, -EINVAL);
240
241 rtm = NLMSG_DATA(m->hdr);
242
243 *table = rtm->rtm_table;
244
245 return 0;
246}
247
89489ef7
TG
248int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char *dst_len) {
249 struct rtmsg *rtm;
250
251 assert_return(m, -EINVAL);
252 assert_return(m->hdr, -EINVAL);
253 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
254 assert_return(dst_len, -EINVAL);
255
256 rtm = NLMSG_DATA(m->hdr);
257
258 *dst_len = rtm->rtm_dst_len;
259
260 return 0;
261}
262
263int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len) {
264 struct rtmsg *rtm;
265
266 assert_return(m, -EINVAL);
267 assert_return(m->hdr, -EINVAL);
268 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
269 assert_return(src_len, -EINVAL);
270
271 rtm = NLMSG_DATA(m->hdr);
272
273 *src_len = rtm->rtm_src_len;
274
275 return 0;
276}
277
278int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret,
279 uint16_t nlmsg_type, int rtm_family,
280 unsigned char rtm_protocol) {
281 struct rtmsg *rtm;
282 int r;
283
284 assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
285 assert_return((nlmsg_type == RTM_GETROUTE && rtm_family == AF_UNSPEC) ||
945c2931 286 IN_SET(rtm_family, AF_INET, AF_INET6), -EINVAL);
89489ef7
TG
287 assert_return(ret, -EINVAL);
288
289 r = message_new(rtnl, ret, nlmsg_type);
290 if (r < 0)
291 return r;
292
293 if (nlmsg_type == RTM_NEWROUTE)
294 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
295
296 rtm = NLMSG_DATA((*ret)->hdr);
297
298 rtm->rtm_family = rtm_family;
299 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
300 rtm->rtm_type = RTN_UNICAST;
301 rtm->rtm_table = RT_TABLE_MAIN;
302 rtm->rtm_protocol = rtm_protocol;
303
304 return 0;
305}
306
307int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) {
308 struct ndmsg *ndm;
309
310 assert_return(m, -EINVAL);
311 assert_return(m->hdr, -EINVAL);
312 assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
313
314 ndm = NLMSG_DATA(m->hdr);
315 ndm->ndm_flags |= flags;
316
317 return 0;
318}
319
320int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state) {
321 struct ndmsg *ndm;
322
323 assert_return(m, -EINVAL);
324 assert_return(m->hdr, -EINVAL);
325 assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
326
327 ndm = NLMSG_DATA(m->hdr);
328 ndm->ndm_state |= state;
329
330 return 0;
331}
332
333int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags) {
334 struct ndmsg *ndm;
335
336 assert_return(m, -EINVAL);
337 assert_return(m->hdr, -EINVAL);
338 assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
339
340 ndm = NLMSG_DATA(m->hdr);
341 *flags = ndm->ndm_flags;
342
343 return 0;
344}
345
346int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state) {
347 struct ndmsg *ndm;
348
349 assert_return(m, -EINVAL);
350 assert_return(m->hdr, -EINVAL);
351 assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
352
353 ndm = NLMSG_DATA(m->hdr);
354 *state = ndm->ndm_state;
355
356 return 0;
357}
358
359int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family) {
360 struct ndmsg *ndm;
361
362 assert_return(m, -EINVAL);
363 assert_return(m->hdr, -EINVAL);
364 assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
365 assert_return(family, -EINVAL);
366
367 ndm = NLMSG_DATA(m->hdr);
368
369 *family = ndm->ndm_family;
370
371 return 0;
372}
373
374int sd_rtnl_message_neigh_get_ifindex(sd_netlink_message *m, int *index) {
375 struct ndmsg *ndm;
376
377 assert_return(m, -EINVAL);
378 assert_return(m->hdr, -EINVAL);
379 assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
380 assert_return(index, -EINVAL);
381
382 ndm = NLMSG_DATA(m->hdr);
383
384 *index = ndm->ndm_ifindex;
385
386 return 0;
387}
388
389int sd_rtnl_message_new_neigh(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int index, int ndm_family) {
390 struct ndmsg *ndm;
391 int r;
392
393 assert_return(rtnl_message_type_is_neigh(nlmsg_type), -EINVAL);
945c2931 394 assert_return(IN_SET(ndm_family, AF_INET, AF_INET6, PF_BRIDGE), -EINVAL);
89489ef7
TG
395 assert_return(ret, -EINVAL);
396
397 r = message_new(rtnl, ret, nlmsg_type);
398 if (r < 0)
399 return r;
400
401 if (nlmsg_type == RTM_NEWNEIGH)
402 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
403
404 ndm = NLMSG_DATA((*ret)->hdr);
405
406 ndm->ndm_family = ndm_family;
407 ndm->ndm_ifindex = index;
408
409 return 0;
410}
411
412int sd_rtnl_message_link_set_flags(sd_netlink_message *m, unsigned flags, unsigned change) {
413 struct ifinfomsg *ifi;
414
415 assert_return(m, -EINVAL);
416 assert_return(m->hdr, -EINVAL);
417 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
418 assert_return(change, -EINVAL);
419
420 ifi = NLMSG_DATA(m->hdr);
421
422 ifi->ifi_flags = flags;
423 ifi->ifi_change = change;
424
425 return 0;
426}
427
428int sd_rtnl_message_link_set_type(sd_netlink_message *m, unsigned type) {
429 struct ifinfomsg *ifi;
430
431 assert_return(m, -EINVAL);
432 assert_return(m->hdr, -EINVAL);
433 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
434
435 ifi = NLMSG_DATA(m->hdr);
436
437 ifi->ifi_type = type;
438
439 return 0;
440}
441
442int sd_rtnl_message_link_set_family(sd_netlink_message *m, unsigned family) {
443 struct ifinfomsg *ifi;
444
445 assert_return(m, -EINVAL);
446 assert_return(m->hdr, -EINVAL);
447 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
448
449 ifi = NLMSG_DATA(m->hdr);
450
451 ifi->ifi_family = family;
452
453 return 0;
454}
455
456int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
457 uint16_t nlmsg_type, int index) {
458 struct ifinfomsg *ifi;
459 int r;
460
461 assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
89489ef7
TG
462 assert_return(ret, -EINVAL);
463
464 r = message_new(rtnl, ret, nlmsg_type);
465 if (r < 0)
466 return r;
467
468 if (nlmsg_type == RTM_NEWLINK)
469 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
470
471 ifi = NLMSG_DATA((*ret)->hdr);
472
473 ifi->ifi_family = AF_UNSPEC;
474 ifi->ifi_index = index;
475
476 return 0;
477}
478
479int sd_rtnl_message_addr_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
480 struct ifaddrmsg *ifa;
481
482 assert_return(m, -EINVAL);
483 assert_return(m->hdr, -EINVAL);
484 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
485
486 ifa = NLMSG_DATA(m->hdr);
487
488 if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
489 (ifa->ifa_family == AF_INET6 && prefixlen > 128))
490 return -ERANGE;
491
492 ifa->ifa_prefixlen = prefixlen;
493
494 return 0;
495}
496
497int sd_rtnl_message_addr_set_flags(sd_netlink_message *m, unsigned char flags) {
498 struct ifaddrmsg *ifa;
499
500 assert_return(m, -EINVAL);
501 assert_return(m->hdr, -EINVAL);
502 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
503
504 ifa = NLMSG_DATA(m->hdr);
505
506 ifa->ifa_flags = flags;
507
508 return 0;
509}
510
511int sd_rtnl_message_addr_set_scope(sd_netlink_message *m, unsigned char scope) {
512 struct ifaddrmsg *ifa;
513
514 assert_return(m, -EINVAL);
515 assert_return(m->hdr, -EINVAL);
516 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
517
518 ifa = NLMSG_DATA(m->hdr);
519
520 ifa->ifa_scope = scope;
521
522 return 0;
523}
524
525int sd_rtnl_message_addr_get_family(sd_netlink_message *m, int *family) {
526 struct ifaddrmsg *ifa;
527
528 assert_return(m, -EINVAL);
529 assert_return(m->hdr, -EINVAL);
530 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
531 assert_return(family, -EINVAL);
532
533 ifa = NLMSG_DATA(m->hdr);
534
535 *family = ifa->ifa_family;
536
537 return 0;
538}
539
540int sd_rtnl_message_addr_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
541 struct ifaddrmsg *ifa;
542
543 assert_return(m, -EINVAL);
544 assert_return(m->hdr, -EINVAL);
545 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
546 assert_return(prefixlen, -EINVAL);
547
548 ifa = NLMSG_DATA(m->hdr);
549
550 *prefixlen = ifa->ifa_prefixlen;
551
552 return 0;
553}
554
555int sd_rtnl_message_addr_get_scope(sd_netlink_message *m, unsigned char *scope) {
556 struct ifaddrmsg *ifa;
557
558 assert_return(m, -EINVAL);
559 assert_return(m->hdr, -EINVAL);
560 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
561 assert_return(scope, -EINVAL);
562
563 ifa = NLMSG_DATA(m->hdr);
564
565 *scope = ifa->ifa_scope;
566
567 return 0;
568}
569
570int sd_rtnl_message_addr_get_flags(sd_netlink_message *m, unsigned char *flags) {
571 struct ifaddrmsg *ifa;
572
573 assert_return(m, -EINVAL);
574 assert_return(m->hdr, -EINVAL);
575 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
576 assert_return(flags, -EINVAL);
577
578 ifa = NLMSG_DATA(m->hdr);
579
580 *flags = ifa->ifa_flags;
581
582 return 0;
583}
584
585int sd_rtnl_message_addr_get_ifindex(sd_netlink_message *m, int *ifindex) {
586 struct ifaddrmsg *ifa;
587
588 assert_return(m, -EINVAL);
589 assert_return(m->hdr, -EINVAL);
590 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
591 assert_return(ifindex, -EINVAL);
592
593 ifa = NLMSG_DATA(m->hdr);
594
595 *ifindex = ifa->ifa_index;
596
597 return 0;
598}
599
600int sd_rtnl_message_new_addr(sd_netlink *rtnl, sd_netlink_message **ret,
601 uint16_t nlmsg_type, int index,
602 int family) {
603 struct ifaddrmsg *ifa;
604 int r;
605
606 assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
607 assert_return((nlmsg_type == RTM_GETADDR && index == 0) ||
608 index > 0, -EINVAL);
609 assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) ||
945c2931 610 IN_SET(family, AF_INET, AF_INET6), -EINVAL);
89489ef7
TG
611 assert_return(ret, -EINVAL);
612
613 r = message_new(rtnl, ret, nlmsg_type);
614 if (r < 0)
615 return r;
616
617 if (nlmsg_type == RTM_GETADDR)
618 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
619
620 ifa = NLMSG_DATA((*ret)->hdr);
621
622 ifa->ifa_index = index;
623 ifa->ifa_family = family;
624 if (family == AF_INET)
625 ifa->ifa_prefixlen = 32;
626 else if (family == AF_INET6)
627 ifa->ifa_prefixlen = 128;
628
629 return 0;
630}
631
632int sd_rtnl_message_new_addr_update(sd_netlink *rtnl, sd_netlink_message **ret,
633 int index, int family) {
634 int r;
635
636 r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
637 if (r < 0)
638 return r;
639
640 (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
641
642 return 0;
643}
644
645int sd_rtnl_message_link_get_ifindex(sd_netlink_message *m, int *ifindex) {
646 struct ifinfomsg *ifi;
647
648 assert_return(m, -EINVAL);
649 assert_return(m->hdr, -EINVAL);
650 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
651 assert_return(ifindex, -EINVAL);
652
653 ifi = NLMSG_DATA(m->hdr);
654
655 *ifindex = ifi->ifi_index;
656
657 return 0;
658}
659
660int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags) {
661 struct ifinfomsg *ifi;
662
663 assert_return(m, -EINVAL);
664 assert_return(m->hdr, -EINVAL);
665 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
666 assert_return(flags, -EINVAL);
667
668 ifi = NLMSG_DATA(m->hdr);
669
670 *flags = ifi->ifi_flags;
671
672 return 0;
673}
674
1c4a6088 675int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type) {
89489ef7
TG
676 struct ifinfomsg *ifi;
677
678 assert_return(m, -EINVAL);
679 assert_return(m->hdr, -EINVAL);
680 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
681 assert_return(type, -EINVAL);
682
683 ifi = NLMSG_DATA(m->hdr);
684
685 *type = ifi->ifi_type;
686
687 return 0;
688}
689
690int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) {
691 assert_return(m, -EINVAL);
692 assert_return(family, -EINVAL);
693
694 assert(m->hdr);
695
696 if (rtnl_message_type_is_link(m->hdr->nlmsg_type)) {
697 struct ifinfomsg *ifi;
698
699 ifi = NLMSG_DATA(m->hdr);
700
701 *family = ifi->ifi_family;
702
703 return 0;
704 } else if (rtnl_message_type_is_route(m->hdr->nlmsg_type)) {
705 struct rtmsg *rtm;
706
707 rtm = NLMSG_DATA(m->hdr);
708
709 *family = rtm->rtm_family;
710
711 return 0;
712 } else if (rtnl_message_type_is_neigh(m->hdr->nlmsg_type)) {
713 struct ndmsg *ndm;
714
715 ndm = NLMSG_DATA(m->hdr);
716
717 *family = ndm->ndm_family;
718
719 return 0;
720 } else if (rtnl_message_type_is_addr(m->hdr->nlmsg_type)) {
721 struct ifaddrmsg *ifa;
722
723 ifa = NLMSG_DATA(m->hdr);
724
725 *family = ifa->ifa_family;
726
bce67bbe
SS
727 return 0;
728 } else if (rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type)) {
729 struct rtmsg *rtm;
730
731 rtm = NLMSG_DATA(m->hdr);
732
733 *family = rtm->rtm_family;
734
89489ef7
TG
735 return 0;
736 }
737
738 return -EOPNOTSUPP;
739}
30746d60
SS
740
741int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family) {
742 struct ifaddrlblmsg *addrlabel;
743 int r;
744
745 assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL);
746 assert_return(ret, -EINVAL);
747
748 r = message_new(rtnl, ret, nlmsg_type);
749 if (r < 0)
750 return r;
751
752 if (nlmsg_type == RTM_NEWADDRLABEL)
753 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
754
755 addrlabel = NLMSG_DATA((*ret)->hdr);
756
757 addrlabel->ifal_family = ifal_family;
758 addrlabel->ifal_index = ifindex;
759
760 return 0;
761}
762
763int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
764 struct ifaddrlblmsg *addrlabel;
765
766 assert_return(m, -EINVAL);
767 assert_return(m->hdr, -EINVAL);
768 assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
769
770 addrlabel = NLMSG_DATA(m->hdr);
771
772 if (prefixlen > 128)
773 return -ERANGE;
774
775 addrlabel->ifal_prefixlen = prefixlen;
776
777 return 0;
778}
d37b7627
SS
779
780int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
781 struct ifaddrlblmsg *addrlabel;
782
783 assert_return(m, -EINVAL);
784 assert_return(m->hdr, -EINVAL);
785 assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
786
787 addrlabel = NLMSG_DATA(m->hdr);
788
789 *prefixlen = addrlabel->ifal_prefixlen;
790
791 return 0;
792}
bce67bbe
SS
793
794int sd_rtnl_message_new_routing_policy_rule(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifal_family) {
795 struct rtmsg *rtm;
796 int r;
797
798 assert_return(rtnl_message_type_is_routing_policy_rule(nlmsg_type), -EINVAL);
799 assert_return(ret, -EINVAL);
800
801 r = message_new(rtnl, ret, nlmsg_type);
802 if (r < 0)
803 return r;
804
805 if (nlmsg_type == RTM_NEWRULE)
806 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
807
808 rtm = NLMSG_DATA((*ret)->hdr);
809 rtm->rtm_family = ifal_family;
810 rtm->rtm_protocol = RTPROT_BOOT;
811 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
812 rtm->rtm_type = RTN_UNICAST;
813
814 return 0;
815}
816
817int sd_rtnl_message_routing_policy_rule_set_tos(sd_netlink_message *m, unsigned char tos) {
818 struct rtmsg *routing_policy_rule;
819
820 assert_return(m, -EINVAL);
821 assert_return(m->hdr, -EINVAL);
822 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
823
824 routing_policy_rule = NLMSG_DATA(m->hdr);
825
826 routing_policy_rule->rtm_tos = tos;
827
828 return 0;
829}
830
831int sd_rtnl_message_routing_policy_rule_get_tos(sd_netlink_message *m, unsigned char *tos) {
832 struct rtmsg *routing_policy_rule;
833
834 assert_return(m, -EINVAL);
835 assert_return(m->hdr, -EINVAL);
836 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
837
838 routing_policy_rule = NLMSG_DATA(m->hdr);
839
840 *tos = routing_policy_rule->rtm_tos;
841
842 return 0;
843}
844
845int sd_rtnl_message_routing_policy_rule_set_table(sd_netlink_message *m, unsigned char table) {
846 struct rtmsg *routing_policy_rule;
847
848 assert_return(m, -EINVAL);
849 assert_return(m->hdr, -EINVAL);
850 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
851
852 routing_policy_rule = NLMSG_DATA(m->hdr);
853
854 routing_policy_rule->rtm_table = table;
855
856 return 0;
857}
858
859int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message *m, unsigned char *table) {
860 struct rtmsg *routing_policy_rule;
861
862 assert_return(m, -EINVAL);
863 assert_return(m->hdr, -EINVAL);
864 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
865
866 routing_policy_rule = NLMSG_DATA(m->hdr);
867
868 *table = routing_policy_rule->rtm_table;
869
870 return 0;
871}
872
873int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type) {
874 struct rtmsg *routing_policy_rule;
875
876 assert_return(m, -EINVAL);
877 assert_return(m->hdr, -EINVAL);
878 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
879
880 routing_policy_rule = NLMSG_DATA(m->hdr);
881
882 routing_policy_rule->rtm_type = type;
883
884 return 0;
885}
886
887int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsigned char *type) {
888 struct rtmsg *routing_policy_rule;
889
890 assert_return(m, -EINVAL);
891 assert_return(m->hdr, -EINVAL);
892 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
893
894 routing_policy_rule = NLMSG_DATA(m->hdr);
895
896 *type = routing_policy_rule->rtm_type;
897
898 return 0;
899}
900
901int sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char len) {
902 struct rtmsg *routing_policy_rule;
903
904 assert_return(m, -EINVAL);
905 assert_return(m->hdr, -EINVAL);
906 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
907
908 routing_policy_rule = NLMSG_DATA(m->hdr);
909
910 routing_policy_rule->rtm_dst_len = len;
911
912 return 0;
913}
914
915int sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char *len) {
916 struct rtmsg *routing_policy_rule;
917
918 assert_return(m, -EINVAL);
919 assert_return(m->hdr, -EINVAL);
920 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
921
922 routing_policy_rule = NLMSG_DATA(m->hdr);
923
924 *len = routing_policy_rule->rtm_dst_len;
925
926 return 0;
927}
928
929int sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(sd_netlink_message *m, unsigned char len) {
930 struct rtmsg *routing_policy_rule;
931
932 assert_return(m, -EINVAL);
933 assert_return(m->hdr, -EINVAL);
934 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
935
936 routing_policy_rule = NLMSG_DATA(m->hdr);
937
938 routing_policy_rule->rtm_src_len = len;
939
940 return 0;
941}
942
943int sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(sd_netlink_message *m, unsigned char *len) {
944 struct rtmsg *routing_policy_rule;
945
946 assert_return(m, -EINVAL);
947 assert_return(m->hdr, -EINVAL);
948 assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
949
950 routing_policy_rule = NLMSG_DATA(m->hdr);
951
952 *len = routing_policy_rule->rtm_src_len;
953
954 return 0;
955}