]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-netlink/netlink-message-rtnl.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <netinet/in.h>
4 #include <linux/fib_rules.h>
5 #include <linux/if_addrlabel.h>
6 #include <linux/if_bridge.h>
7 #include <linux/nexthop.h>
11 #include "sd-netlink.h"
13 #include "format-util.h"
14 #include "netlink-internal.h"
15 #include "netlink-types.h"
16 #include "netlink-util.h"
17 #include "socket-util.h"
19 static bool rtnl_message_type_is_neigh(uint16_t type
) {
20 return IN_SET(type
, RTM_NEWNEIGH
, RTM_GETNEIGH
, RTM_DELNEIGH
);
23 static bool rtnl_message_type_is_route(uint16_t type
) {
24 return IN_SET(type
, RTM_NEWROUTE
, RTM_GETROUTE
, RTM_DELROUTE
);
27 static bool rtnl_message_type_is_nexthop(uint16_t type
) {
28 return IN_SET(type
, RTM_NEWNEXTHOP
, RTM_GETNEXTHOP
, RTM_DELNEXTHOP
);
31 static bool rtnl_message_type_is_link(uint16_t type
) {
33 RTM_NEWLINK
, RTM_SETLINK
, RTM_GETLINK
, RTM_DELLINK
,
34 RTM_NEWLINKPROP
, RTM_DELLINKPROP
, RTM_GETLINKPROP
);
37 static bool rtnl_message_type_is_addr(uint16_t type
) {
38 return IN_SET(type
, RTM_NEWADDR
, RTM_GETADDR
, RTM_DELADDR
);
41 static bool rtnl_message_type_is_addrlabel(uint16_t type
) {
42 return IN_SET(type
, RTM_NEWADDRLABEL
, RTM_DELADDRLABEL
, RTM_GETADDRLABEL
);
45 static bool rtnl_message_type_is_routing_policy_rule(uint16_t type
) {
46 return IN_SET(type
, RTM_NEWRULE
, RTM_DELRULE
, RTM_GETRULE
);
49 static bool rtnl_message_type_is_traffic_control(uint16_t type
) {
51 RTM_NEWQDISC
, RTM_DELQDISC
, RTM_GETQDISC
,
52 RTM_NEWTCLASS
, RTM_DELTCLASS
, RTM_GETTCLASS
);
55 static bool rtnl_message_type_is_mdb(uint16_t type
) {
56 return IN_SET(type
, RTM_NEWMDB
, RTM_DELMDB
, RTM_GETMDB
);
59 int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message
*m
, unsigned char prefixlen
) {
62 assert_return(m
, -EINVAL
);
63 assert_return(m
->hdr
, -EINVAL
);
64 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
66 rtm
= NLMSG_DATA(m
->hdr
);
68 if ((rtm
->rtm_family
== AF_INET
&& prefixlen
> 32) ||
69 (rtm
->rtm_family
== AF_INET6
&& prefixlen
> 128))
72 rtm
->rtm_dst_len
= prefixlen
;
77 int sd_rtnl_message_route_set_src_prefixlen(sd_netlink_message
*m
, unsigned char prefixlen
) {
80 assert_return(m
, -EINVAL
);
81 assert_return(m
->hdr
, -EINVAL
);
82 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
84 rtm
= NLMSG_DATA(m
->hdr
);
86 if ((rtm
->rtm_family
== AF_INET
&& prefixlen
> 32) ||
87 (rtm
->rtm_family
== AF_INET6
&& prefixlen
> 128))
90 rtm
->rtm_src_len
= prefixlen
;
95 int sd_rtnl_message_route_set_scope(sd_netlink_message
*m
, unsigned char scope
) {
98 assert_return(m
, -EINVAL
);
99 assert_return(m
->hdr
, -EINVAL
);
100 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
102 rtm
= NLMSG_DATA(m
->hdr
);
104 rtm
->rtm_scope
= scope
;
109 int sd_rtnl_message_route_set_flags(sd_netlink_message
*m
, unsigned flags
) {
112 assert_return(m
, -EINVAL
);
113 assert_return(m
->hdr
, -EINVAL
);
114 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
116 rtm
= NLMSG_DATA(m
->hdr
);
118 rtm
->rtm_flags
= flags
;
123 int sd_rtnl_message_route_get_flags(sd_netlink_message
*m
, unsigned *flags
) {
126 assert_return(m
, -EINVAL
);
127 assert_return(m
->hdr
, -EINVAL
);
128 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
129 assert_return(flags
, -EINVAL
);
131 rtm
= NLMSG_DATA(m
->hdr
);
133 *flags
= rtm
->rtm_flags
;
138 int sd_rtnl_message_route_set_table(sd_netlink_message
*m
, unsigned char table
) {
141 assert_return(m
, -EINVAL
);
142 assert_return(m
->hdr
, -EINVAL
);
143 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
145 rtm
= NLMSG_DATA(m
->hdr
);
147 rtm
->rtm_table
= table
;
152 int sd_rtnl_message_route_get_family(sd_netlink_message
*m
, int *family
) {
155 assert_return(m
, -EINVAL
);
156 assert_return(m
->hdr
, -EINVAL
);
157 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
158 assert_return(family
, -EINVAL
);
160 rtm
= NLMSG_DATA(m
->hdr
);
162 *family
= rtm
->rtm_family
;
167 int sd_rtnl_message_route_get_type(sd_netlink_message
*m
, unsigned char *type
) {
170 assert_return(m
, -EINVAL
);
171 assert_return(m
->hdr
, -EINVAL
);
172 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
173 assert_return(type
, -EINVAL
);
175 rtm
= NLMSG_DATA(m
->hdr
);
177 *type
= rtm
->rtm_type
;
182 int sd_rtnl_message_route_set_type(sd_netlink_message
*m
, unsigned char type
) {
185 assert_return(m
, -EINVAL
);
186 assert_return(m
->hdr
, -EINVAL
);
187 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
189 rtm
= NLMSG_DATA(m
->hdr
);
191 rtm
->rtm_type
= type
;
196 int sd_rtnl_message_route_get_protocol(sd_netlink_message
*m
, unsigned char *protocol
) {
199 assert_return(m
, -EINVAL
);
200 assert_return(m
->hdr
, -EINVAL
);
201 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
202 assert_return(protocol
, -EINVAL
);
204 rtm
= NLMSG_DATA(m
->hdr
);
206 *protocol
= rtm
->rtm_protocol
;
211 int sd_rtnl_message_route_get_scope(sd_netlink_message
*m
, unsigned char *scope
) {
214 assert_return(m
, -EINVAL
);
215 assert_return(m
->hdr
, -EINVAL
);
216 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
217 assert_return(scope
, -EINVAL
);
219 rtm
= NLMSG_DATA(m
->hdr
);
221 *scope
= rtm
->rtm_scope
;
226 int sd_rtnl_message_route_get_tos(sd_netlink_message
*m
, uint8_t *tos
) {
229 assert_return(m
, -EINVAL
);
230 assert_return(m
->hdr
, -EINVAL
);
231 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
232 assert_return(tos
, -EINVAL
);
234 rtm
= NLMSG_DATA(m
->hdr
);
241 int sd_rtnl_message_route_get_table(sd_netlink_message
*m
, unsigned char *table
) {
244 assert_return(m
, -EINVAL
);
245 assert_return(m
->hdr
, -EINVAL
);
246 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
247 assert_return(table
, -EINVAL
);
249 rtm
= NLMSG_DATA(m
->hdr
);
251 *table
= rtm
->rtm_table
;
256 int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message
*m
, unsigned char *dst_len
) {
259 assert_return(m
, -EINVAL
);
260 assert_return(m
->hdr
, -EINVAL
);
261 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
262 assert_return(dst_len
, -EINVAL
);
264 rtm
= NLMSG_DATA(m
->hdr
);
266 *dst_len
= rtm
->rtm_dst_len
;
271 int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message
*m
, unsigned char *src_len
) {
274 assert_return(m
, -EINVAL
);
275 assert_return(m
->hdr
, -EINVAL
);
276 assert_return(rtnl_message_type_is_route(m
->hdr
->nlmsg_type
), -EINVAL
);
277 assert_return(src_len
, -EINVAL
);
279 rtm
= NLMSG_DATA(m
->hdr
);
281 *src_len
= rtm
->rtm_src_len
;
286 int sd_rtnl_message_new_route(sd_netlink
*rtnl
, sd_netlink_message
**ret
,
287 uint16_t nlmsg_type
, int rtm_family
,
288 unsigned char rtm_protocol
) {
292 assert_return(rtnl_message_type_is_route(nlmsg_type
), -EINVAL
);
293 assert_return((nlmsg_type
== RTM_GETROUTE
&& rtm_family
== AF_UNSPEC
) ||
294 IN_SET(rtm_family
, AF_INET
, AF_INET6
), -EINVAL
);
295 assert_return(ret
, -EINVAL
);
297 r
= message_new(rtnl
, ret
, nlmsg_type
);
301 if (nlmsg_type
== RTM_NEWROUTE
)
302 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_APPEND
;
304 rtm
= NLMSG_DATA((*ret
)->hdr
);
306 rtm
->rtm_family
= rtm_family
;
307 rtm
->rtm_protocol
= rtm_protocol
;
312 int sd_rtnl_message_new_nexthop(sd_netlink
*rtnl
, sd_netlink_message
**ret
,
313 uint16_t nlmsg_type
, int nh_family
,
314 unsigned char nh_protocol
) {
318 assert_return(rtnl_message_type_is_nexthop(nlmsg_type
), -EINVAL
);
319 switch (nlmsg_type
) {
321 assert_return(nh_family
== AF_UNSPEC
, -EINVAL
);
324 assert_return(nh_protocol
== RTPROT_UNSPEC
, -EINVAL
);
327 assert_return(IN_SET(nh_family
, AF_UNSPEC
, AF_INET
, AF_INET6
), -EINVAL
);
330 assert_not_reached();
332 assert_return(ret
, -EINVAL
);
334 r
= message_new(rtnl
, ret
, nlmsg_type
);
338 if (nlmsg_type
== RTM_NEWNEXTHOP
)
339 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_APPEND
;
341 nhm
= NLMSG_DATA((*ret
)->hdr
);
343 nhm
->nh_family
= nh_family
;
344 nhm
->nh_scope
= RT_SCOPE_UNIVERSE
;
345 nhm
->nh_protocol
= nh_protocol
;
350 int sd_rtnl_message_nexthop_set_flags(sd_netlink_message
*m
, uint8_t flags
) {
353 assert_return(m
, -EINVAL
);
354 assert_return(m
->hdr
, -EINVAL
);
355 assert_return(m
->hdr
->nlmsg_type
== RTM_NEWNEXTHOP
, -EINVAL
);
357 nhm
= NLMSG_DATA(m
->hdr
);
358 nhm
->nh_flags
= flags
;
363 int sd_rtnl_message_nexthop_get_flags(sd_netlink_message
*m
, uint8_t *ret
) {
366 assert_return(m
, -EINVAL
);
367 assert_return(m
->hdr
, -EINVAL
);
368 assert_return(rtnl_message_type_is_nexthop(m
->hdr
->nlmsg_type
), -EINVAL
);
369 assert_return(ret
, -EINVAL
);
371 nhm
= NLMSG_DATA(m
->hdr
);
372 *ret
= nhm
->nh_flags
;
377 int sd_rtnl_message_nexthop_get_family(sd_netlink_message
*m
, uint8_t *family
) {
380 assert_return(m
, -EINVAL
);
381 assert_return(m
->hdr
, -EINVAL
);
382 assert_return(rtnl_message_type_is_nexthop(m
->hdr
->nlmsg_type
), -EINVAL
);
383 assert_return(family
, -EINVAL
);
385 nhm
= NLMSG_DATA(m
->hdr
);
386 *family
= nhm
->nh_family
;
391 int sd_rtnl_message_nexthop_get_protocol(sd_netlink_message
*m
, uint8_t *protocol
) {
394 assert_return(m
, -EINVAL
);
395 assert_return(m
->hdr
, -EINVAL
);
396 assert_return(rtnl_message_type_is_nexthop(m
->hdr
->nlmsg_type
), -EINVAL
);
397 assert_return(protocol
, -EINVAL
);
399 nhm
= NLMSG_DATA(m
->hdr
);
400 *protocol
= nhm
->nh_protocol
;
405 int sd_rtnl_message_neigh_set_flags(sd_netlink_message
*m
, uint8_t flags
) {
408 assert_return(m
, -EINVAL
);
409 assert_return(m
->hdr
, -EINVAL
);
410 assert_return(rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
), -EINVAL
);
412 ndm
= NLMSG_DATA(m
->hdr
);
413 ndm
->ndm_flags
= flags
;
418 int sd_rtnl_message_neigh_set_state(sd_netlink_message
*m
, uint16_t state
) {
421 assert_return(m
, -EINVAL
);
422 assert_return(m
->hdr
, -EINVAL
);
423 assert_return(rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
), -EINVAL
);
425 ndm
= NLMSG_DATA(m
->hdr
);
426 ndm
->ndm_state
= state
;
431 int sd_rtnl_message_neigh_get_flags(sd_netlink_message
*m
, uint8_t *flags
) {
434 assert_return(m
, -EINVAL
);
435 assert_return(m
->hdr
, -EINVAL
);
436 assert_return(rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
), -EINVAL
);
438 ndm
= NLMSG_DATA(m
->hdr
);
439 *flags
= ndm
->ndm_flags
;
444 int sd_rtnl_message_neigh_get_state(sd_netlink_message
*m
, uint16_t *state
) {
447 assert_return(m
, -EINVAL
);
448 assert_return(m
->hdr
, -EINVAL
);
449 assert_return(rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
), -EINVAL
);
451 ndm
= NLMSG_DATA(m
->hdr
);
452 *state
= ndm
->ndm_state
;
457 int sd_rtnl_message_neigh_get_family(sd_netlink_message
*m
, int *family
) {
460 assert_return(m
, -EINVAL
);
461 assert_return(m
->hdr
, -EINVAL
);
462 assert_return(rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
), -EINVAL
);
463 assert_return(family
, -EINVAL
);
465 ndm
= NLMSG_DATA(m
->hdr
);
467 *family
= ndm
->ndm_family
;
472 int sd_rtnl_message_neigh_get_ifindex(sd_netlink_message
*m
, int *index
) {
475 assert_return(m
, -EINVAL
);
476 assert_return(m
->hdr
, -EINVAL
);
477 assert_return(rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
), -EINVAL
);
478 assert_return(index
, -EINVAL
);
480 ndm
= NLMSG_DATA(m
->hdr
);
482 *index
= ndm
->ndm_ifindex
;
487 int sd_rtnl_message_new_neigh(
489 sd_netlink_message
**ret
,
497 assert_return(rtnl_message_type_is_neigh(nlmsg_type
), -EINVAL
);
498 assert_return(IN_SET(ndm_family
, AF_UNSPEC
, AF_INET
, AF_INET6
, AF_BRIDGE
), -EINVAL
);
499 assert_return(ret
, -EINVAL
);
501 r
= message_new(rtnl
, ret
, nlmsg_type
);
505 if (nlmsg_type
== RTM_NEWNEIGH
) {
506 if (ndm_family
== AF_BRIDGE
)
507 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_APPEND
;
509 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_REPLACE
;
512 ndm
= NLMSG_DATA((*ret
)->hdr
);
514 ndm
->ndm_family
= ndm_family
;
515 ndm
->ndm_ifindex
= index
;
520 int sd_rtnl_message_link_set_flags(sd_netlink_message
*m
, unsigned flags
, unsigned change
) {
521 struct ifinfomsg
*ifi
;
523 assert_return(m
, -EINVAL
);
524 assert_return(m
->hdr
, -EINVAL
);
525 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
526 assert_return(change
!= 0, -EINVAL
);
528 ifi
= NLMSG_DATA(m
->hdr
);
530 ifi
->ifi_flags
= flags
;
531 ifi
->ifi_change
= change
;
536 int sd_rtnl_message_link_set_type(sd_netlink_message
*m
, unsigned type
) {
537 struct ifinfomsg
*ifi
;
539 assert_return(m
, -EINVAL
);
540 assert_return(m
->hdr
, -EINVAL
);
541 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
543 ifi
= NLMSG_DATA(m
->hdr
);
545 ifi
->ifi_type
= type
;
550 int sd_rtnl_message_link_set_family(sd_netlink_message
*m
, unsigned family
) {
551 struct ifinfomsg
*ifi
;
553 assert_return(m
, -EINVAL
);
554 assert_return(m
->hdr
, -EINVAL
);
555 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
557 ifi
= NLMSG_DATA(m
->hdr
);
559 ifi
->ifi_family
= family
;
564 int sd_rtnl_message_new_link(sd_netlink
*rtnl
, sd_netlink_message
**ret
,
565 uint16_t nlmsg_type
, int index
) {
566 struct ifinfomsg
*ifi
;
569 assert_return(rtnl_message_type_is_link(nlmsg_type
), -EINVAL
);
570 assert_return(ret
, -EINVAL
);
572 r
= message_new(rtnl
, ret
, nlmsg_type
);
576 if (nlmsg_type
== RTM_NEWLINK
)
577 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
578 else if (nlmsg_type
== RTM_NEWLINKPROP
)
579 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_APPEND
;
581 ifi
= NLMSG_DATA((*ret
)->hdr
);
583 ifi
->ifi_family
= AF_UNSPEC
;
584 ifi
->ifi_index
= index
;
589 int sd_rtnl_message_addr_set_prefixlen(sd_netlink_message
*m
, unsigned char prefixlen
) {
590 struct ifaddrmsg
*ifa
;
592 assert_return(m
, -EINVAL
);
593 assert_return(m
->hdr
, -EINVAL
);
594 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
596 ifa
= NLMSG_DATA(m
->hdr
);
598 if ((ifa
->ifa_family
== AF_INET
&& prefixlen
> 32) ||
599 (ifa
->ifa_family
== AF_INET6
&& prefixlen
> 128))
602 ifa
->ifa_prefixlen
= prefixlen
;
607 int sd_rtnl_message_addr_set_flags(sd_netlink_message
*m
, unsigned char flags
) {
608 struct ifaddrmsg
*ifa
;
610 assert_return(m
, -EINVAL
);
611 assert_return(m
->hdr
, -EINVAL
);
612 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
614 ifa
= NLMSG_DATA(m
->hdr
);
616 ifa
->ifa_flags
= flags
;
621 int sd_rtnl_message_addr_set_scope(sd_netlink_message
*m
, unsigned char scope
) {
622 struct ifaddrmsg
*ifa
;
624 assert_return(m
, -EINVAL
);
625 assert_return(m
->hdr
, -EINVAL
);
626 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
628 ifa
= NLMSG_DATA(m
->hdr
);
630 ifa
->ifa_scope
= scope
;
635 int sd_rtnl_message_addr_get_family(sd_netlink_message
*m
, int *ret_family
) {
636 struct ifaddrmsg
*ifa
;
638 assert_return(m
, -EINVAL
);
639 assert_return(m
->hdr
, -EINVAL
);
640 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
641 assert_return(ret_family
, -EINVAL
);
643 ifa
= NLMSG_DATA(m
->hdr
);
645 *ret_family
= ifa
->ifa_family
;
650 int sd_rtnl_message_addr_get_prefixlen(sd_netlink_message
*m
, unsigned char *ret_prefixlen
) {
651 struct ifaddrmsg
*ifa
;
653 assert_return(m
, -EINVAL
);
654 assert_return(m
->hdr
, -EINVAL
);
655 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
656 assert_return(ret_prefixlen
, -EINVAL
);
658 ifa
= NLMSG_DATA(m
->hdr
);
660 *ret_prefixlen
= ifa
->ifa_prefixlen
;
665 int sd_rtnl_message_addr_get_scope(sd_netlink_message
*m
, unsigned char *ret_scope
) {
666 struct ifaddrmsg
*ifa
;
668 assert_return(m
, -EINVAL
);
669 assert_return(m
->hdr
, -EINVAL
);
670 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
671 assert_return(ret_scope
, -EINVAL
);
673 ifa
= NLMSG_DATA(m
->hdr
);
675 *ret_scope
= ifa
->ifa_scope
;
680 int sd_rtnl_message_addr_get_flags(sd_netlink_message
*m
, unsigned char *ret_flags
) {
681 struct ifaddrmsg
*ifa
;
683 assert_return(m
, -EINVAL
);
684 assert_return(m
->hdr
, -EINVAL
);
685 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
686 assert_return(ret_flags
, -EINVAL
);
688 ifa
= NLMSG_DATA(m
->hdr
);
690 *ret_flags
= ifa
->ifa_flags
;
695 int sd_rtnl_message_addr_get_ifindex(sd_netlink_message
*m
, int *ret_ifindex
) {
696 struct ifaddrmsg
*ifa
;
698 assert_return(m
, -EINVAL
);
699 assert_return(m
->hdr
, -EINVAL
);
700 assert_return(rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
), -EINVAL
);
701 assert_return(ret_ifindex
, -EINVAL
);
703 ifa
= NLMSG_DATA(m
->hdr
);
705 *ret_ifindex
= ifa
->ifa_index
;
710 int sd_rtnl_message_new_addr(
712 sd_netlink_message
**ret
,
717 struct ifaddrmsg
*ifa
;
720 assert_return(rtnl_message_type_is_addr(nlmsg_type
), -EINVAL
);
721 assert_return((nlmsg_type
== RTM_GETADDR
&& index
== 0) ||
723 assert_return((nlmsg_type
== RTM_GETADDR
&& family
== AF_UNSPEC
) ||
724 IN_SET(family
, AF_INET
, AF_INET6
), -EINVAL
);
725 assert_return(ret
, -EINVAL
);
727 r
= message_new(rtnl
, ret
, nlmsg_type
);
731 ifa
= NLMSG_DATA((*ret
)->hdr
);
733 ifa
->ifa_index
= index
;
734 ifa
->ifa_family
= family
;
739 int sd_rtnl_message_new_addr_update(
741 sd_netlink_message
**ret
,
746 r
= sd_rtnl_message_new_addr(rtnl
, ret
, RTM_NEWADDR
, index
, family
);
750 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_REPLACE
;
755 int sd_rtnl_message_link_get_ifindex(sd_netlink_message
*m
, int *ifindex
) {
756 struct ifinfomsg
*ifi
;
758 assert_return(m
, -EINVAL
);
759 assert_return(m
->hdr
, -EINVAL
);
760 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
761 assert_return(ifindex
, -EINVAL
);
763 ifi
= NLMSG_DATA(m
->hdr
);
765 *ifindex
= ifi
->ifi_index
;
770 int sd_rtnl_message_link_get_flags(sd_netlink_message
*m
, unsigned *flags
) {
771 struct ifinfomsg
*ifi
;
773 assert_return(m
, -EINVAL
);
774 assert_return(m
->hdr
, -EINVAL
);
775 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
776 assert_return(flags
, -EINVAL
);
778 ifi
= NLMSG_DATA(m
->hdr
);
780 *flags
= ifi
->ifi_flags
;
785 int sd_rtnl_message_link_get_type(sd_netlink_message
*m
, unsigned short *type
) {
786 struct ifinfomsg
*ifi
;
788 assert_return(m
, -EINVAL
);
789 assert_return(m
->hdr
, -EINVAL
);
790 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
791 assert_return(type
, -EINVAL
);
793 ifi
= NLMSG_DATA(m
->hdr
);
795 *type
= ifi
->ifi_type
;
800 int sd_rtnl_message_get_family(sd_netlink_message
*m
, int *family
) {
801 assert_return(m
, -EINVAL
);
802 assert_return(family
, -EINVAL
);
806 if (rtnl_message_type_is_link(m
->hdr
->nlmsg_type
)) {
807 struct ifinfomsg
*ifi
;
809 ifi
= NLMSG_DATA(m
->hdr
);
811 *family
= ifi
->ifi_family
;
814 } else if (rtnl_message_type_is_route(m
->hdr
->nlmsg_type
)) {
817 rtm
= NLMSG_DATA(m
->hdr
);
819 *family
= rtm
->rtm_family
;
822 } else if (rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
)) {
825 ndm
= NLMSG_DATA(m
->hdr
);
827 *family
= ndm
->ndm_family
;
830 } else if (rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
)) {
831 struct ifaddrmsg
*ifa
;
833 ifa
= NLMSG_DATA(m
->hdr
);
835 *family
= ifa
->ifa_family
;
838 } else if (rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
)) {
841 rtm
= NLMSG_DATA(m
->hdr
);
843 *family
= rtm
->rtm_family
;
846 } else if (rtnl_message_type_is_nexthop(m
->hdr
->nlmsg_type
)) {
849 nhm
= NLMSG_DATA(m
->hdr
);
851 *family
= nhm
->nh_family
;
859 int sd_rtnl_message_new_addrlabel(
861 sd_netlink_message
**ret
,
866 struct ifaddrlblmsg
*addrlabel
;
869 assert_return(rtnl_message_type_is_addrlabel(nlmsg_type
), -EINVAL
);
870 assert_return(ret
, -EINVAL
);
872 r
= message_new(rtnl
, ret
, nlmsg_type
);
876 if (nlmsg_type
== RTM_NEWADDRLABEL
)
877 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
879 addrlabel
= NLMSG_DATA((*ret
)->hdr
);
881 addrlabel
->ifal_family
= ifal_family
;
882 addrlabel
->ifal_index
= ifindex
;
887 int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message
*m
, unsigned char prefixlen
) {
888 struct ifaddrlblmsg
*addrlabel
;
890 assert_return(m
, -EINVAL
);
891 assert_return(m
->hdr
, -EINVAL
);
892 assert_return(rtnl_message_type_is_addrlabel(m
->hdr
->nlmsg_type
), -EINVAL
);
894 addrlabel
= NLMSG_DATA(m
->hdr
);
899 addrlabel
->ifal_prefixlen
= prefixlen
;
904 int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message
*m
, unsigned char *prefixlen
) {
905 struct ifaddrlblmsg
*addrlabel
;
907 assert_return(m
, -EINVAL
);
908 assert_return(m
->hdr
, -EINVAL
);
909 assert_return(rtnl_message_type_is_addrlabel(m
->hdr
->nlmsg_type
), -EINVAL
);
911 addrlabel
= NLMSG_DATA(m
->hdr
);
913 *prefixlen
= addrlabel
->ifal_prefixlen
;
918 int sd_rtnl_message_new_routing_policy_rule(
920 sd_netlink_message
**ret
,
924 struct fib_rule_hdr
*frh
;
927 assert_return(rtnl_message_type_is_routing_policy_rule(nlmsg_type
), -EINVAL
);
928 assert_return(ret
, -EINVAL
);
930 r
= message_new(rtnl
, ret
, nlmsg_type
);
934 if (nlmsg_type
== RTM_NEWRULE
)
935 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
937 frh
= NLMSG_DATA((*ret
)->hdr
);
938 frh
->family
= ifal_family
;
943 int sd_rtnl_message_routing_policy_rule_set_tos(sd_netlink_message
*m
, uint8_t tos
) {
944 struct fib_rule_hdr
*frh
;
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
);
950 frh
= NLMSG_DATA(m
->hdr
);
957 int sd_rtnl_message_routing_policy_rule_get_tos(sd_netlink_message
*m
, uint8_t *tos
) {
958 struct fib_rule_hdr
*frh
;
960 assert_return(m
, -EINVAL
);
961 assert_return(m
->hdr
, -EINVAL
);
962 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
964 frh
= NLMSG_DATA(m
->hdr
);
971 int sd_rtnl_message_routing_policy_rule_set_table(sd_netlink_message
*m
, uint8_t table
) {
972 struct fib_rule_hdr
*frh
;
974 assert_return(m
, -EINVAL
);
975 assert_return(m
->hdr
, -EINVAL
);
976 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
978 frh
= NLMSG_DATA(m
->hdr
);
985 int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message
*m
, uint8_t *table
) {
986 struct fib_rule_hdr
*frh
;
988 assert_return(m
, -EINVAL
);
989 assert_return(m
->hdr
, -EINVAL
);
990 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
992 frh
= NLMSG_DATA(m
->hdr
);
999 int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message
*m
, uint32_t flags
) {
1000 struct fib_rule_hdr
*frh
;
1002 assert_return(m
, -EINVAL
);
1003 assert_return(m
->hdr
, -EINVAL
);
1004 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1006 frh
= NLMSG_DATA(m
->hdr
);
1012 int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message
*m
, uint32_t *flags
) {
1013 struct fib_rule_hdr
*frh
;
1015 assert_return(m
, -EINVAL
);
1016 assert_return(m
->hdr
, -EINVAL
);
1017 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1019 frh
= NLMSG_DATA(m
->hdr
);
1020 *flags
= frh
->flags
;
1025 int sd_rtnl_message_routing_policy_rule_set_fib_type(sd_netlink_message
*m
, uint8_t type
) {
1026 struct fib_rule_hdr
*frh
;
1028 assert_return(m
, -EINVAL
);
1029 assert_return(m
->hdr
, -EINVAL
);
1030 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1032 frh
= NLMSG_DATA(m
->hdr
);
1039 int sd_rtnl_message_routing_policy_rule_get_fib_type(sd_netlink_message
*m
, uint8_t *type
) {
1040 struct fib_rule_hdr
*frh
;
1042 assert_return(m
, -EINVAL
);
1043 assert_return(m
->hdr
, -EINVAL
);
1044 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1046 frh
= NLMSG_DATA(m
->hdr
);
1048 *type
= frh
->action
;
1053 int sd_rtnl_message_routing_policy_rule_set_fib_dst_prefixlen(sd_netlink_message
*m
, uint8_t len
) {
1054 struct fib_rule_hdr
*frh
;
1056 assert_return(m
, -EINVAL
);
1057 assert_return(m
->hdr
, -EINVAL
);
1058 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1060 frh
= NLMSG_DATA(m
->hdr
);
1067 int sd_rtnl_message_routing_policy_rule_get_fib_dst_prefixlen(sd_netlink_message
*m
, uint8_t *len
) {
1068 struct fib_rule_hdr
*frh
;
1070 assert_return(m
, -EINVAL
);
1071 assert_return(m
->hdr
, -EINVAL
);
1072 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1074 frh
= NLMSG_DATA(m
->hdr
);
1076 *len
= frh
->dst_len
;
1081 int sd_rtnl_message_routing_policy_rule_set_fib_src_prefixlen(sd_netlink_message
*m
, uint8_t len
) {
1082 struct fib_rule_hdr
*frh
;
1084 assert_return(m
, -EINVAL
);
1085 assert_return(m
->hdr
, -EINVAL
);
1086 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1088 frh
= NLMSG_DATA(m
->hdr
);
1095 int sd_rtnl_message_routing_policy_rule_get_fib_src_prefixlen(sd_netlink_message
*m
, uint8_t *len
) {
1096 struct fib_rule_hdr
*frh
;
1098 assert_return(m
, -EINVAL
);
1099 assert_return(m
->hdr
, -EINVAL
);
1100 assert_return(rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
), -EINVAL
);
1102 frh
= NLMSG_DATA(m
->hdr
);
1104 *len
= frh
->src_len
;
1109 int sd_rtnl_message_new_traffic_control(
1111 sd_netlink_message
**ret
,
1112 uint16_t nlmsg_type
,
1120 assert_return(rtnl_message_type_is_traffic_control(nlmsg_type
), -EINVAL
);
1121 assert_return(ret
, -EINVAL
);
1123 r
= message_new(rtnl
, ret
, nlmsg_type
);
1127 if (IN_SET(nlmsg_type
, RTM_NEWQDISC
, RTM_NEWTCLASS
))
1128 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1130 tcm
= NLMSG_DATA((*ret
)->hdr
);
1131 tcm
->tcm_ifindex
= ifindex
;
1132 tcm
->tcm_handle
= handle
;
1133 tcm
->tcm_parent
= parent
;
1138 int sd_rtnl_message_traffic_control_get_ifindex(sd_netlink_message
*m
, int *ret
) {
1141 assert_return(m
, -EINVAL
);
1142 assert_return(m
->hdr
, -EINVAL
);
1143 assert_return(rtnl_message_type_is_traffic_control(m
->hdr
->nlmsg_type
), -EINVAL
);
1144 assert_return(ret
, -EINVAL
);
1146 tcm
= NLMSG_DATA(m
->hdr
);
1147 *ret
= tcm
->tcm_ifindex
;
1152 int sd_rtnl_message_traffic_control_get_handle(sd_netlink_message
*m
, uint32_t *ret
) {
1155 assert_return(m
, -EINVAL
);
1156 assert_return(m
->hdr
, -EINVAL
);
1157 assert_return(rtnl_message_type_is_traffic_control(m
->hdr
->nlmsg_type
), -EINVAL
);
1158 assert_return(ret
, -EINVAL
);
1160 tcm
= NLMSG_DATA(m
->hdr
);
1161 *ret
= tcm
->tcm_handle
;
1166 int sd_rtnl_message_traffic_control_get_parent(sd_netlink_message
*m
, uint32_t *ret
) {
1169 assert_return(m
, -EINVAL
);
1170 assert_return(m
->hdr
, -EINVAL
);
1171 assert_return(rtnl_message_type_is_traffic_control(m
->hdr
->nlmsg_type
), -EINVAL
);
1172 assert_return(ret
, -EINVAL
);
1174 tcm
= NLMSG_DATA(m
->hdr
);
1175 *ret
= tcm
->tcm_parent
;
1180 int sd_rtnl_message_new_mdb(
1182 sd_netlink_message
**ret
,
1183 uint16_t nlmsg_type
,
1186 struct br_port_msg
*bpm
;
1189 assert_return(rtnl_message_type_is_mdb(nlmsg_type
), -EINVAL
);
1190 assert_return(ret
, -EINVAL
);
1192 r
= message_new(rtnl
, ret
, nlmsg_type
);
1196 if (nlmsg_type
== RTM_NEWMDB
)
1197 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1199 bpm
= NLMSG_DATA((*ret
)->hdr
);
1200 bpm
->family
= AF_BRIDGE
;
1201 bpm
->ifindex
= mdb_ifindex
;