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