]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-netlink/netlink-message-rtnl.c
ee6bba8d03a7c05694834faae7f3b61e2a8651ef
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/fib_rules.h>
4 #include <linux/if_addrlabel.h>
5 #include <linux/if_bridge.h>
6 #include <linux/nexthop.h>
8 #include "sd-netlink.h"
10 #include "in-addr-util.h"
11 #include "netlink-internal.h"
13 static bool rtnl_message_type_is_neigh(uint16_t type
) {
14 return IN_SET(type
, RTM_NEWNEIGH
, RTM_GETNEIGH
, RTM_DELNEIGH
);
17 static bool rtnl_message_type_is_route(uint16_t type
) {
18 return IN_SET(type
, RTM_NEWROUTE
, RTM_GETROUTE
, RTM_DELROUTE
);
21 static bool rtnl_message_type_is_nexthop(uint16_t type
) {
22 return IN_SET(type
, RTM_NEWNEXTHOP
, RTM_GETNEXTHOP
, RTM_DELNEXTHOP
);
25 static bool rtnl_message_type_is_link(uint16_t type
) {
27 RTM_NEWLINK
, RTM_SETLINK
, RTM_GETLINK
, RTM_DELLINK
,
28 RTM_NEWLINKPROP
, RTM_DELLINKPROP
, RTM_GETLINKPROP
);
31 static bool rtnl_message_type_is_addr(uint16_t type
) {
32 return IN_SET(type
, RTM_NEWADDR
, RTM_GETADDR
, RTM_DELADDR
);
35 static bool rtnl_message_type_is_addrlabel(uint16_t type
) {
36 return IN_SET(type
, RTM_NEWADDRLABEL
, RTM_DELADDRLABEL
, RTM_GETADDRLABEL
);
39 static bool rtnl_message_type_is_routing_policy_rule(uint16_t type
) {
40 return IN_SET(type
, RTM_NEWRULE
, RTM_DELRULE
, RTM_GETRULE
);
43 static bool rtnl_message_type_is_traffic_control(uint16_t type
) {
45 RTM_NEWQDISC
, RTM_DELQDISC
, RTM_GETQDISC
,
46 RTM_NEWTCLASS
, RTM_DELTCLASS
, RTM_GETTCLASS
);
49 static bool rtnl_message_type_is_mdb(uint16_t type
) {
50 return IN_SET(type
, RTM_NEWMDB
, RTM_DELMDB
, RTM_GETMDB
);
53 static bool rtnl_message_type_is_nsid(uint16_t type
) {
54 return IN_SET(type
, RTM_NEWNSID
, RTM_DELNSID
, RTM_GETNSID
);
57 #define DEFINE_RTNL_MESSAGE_SETTER(class, header_type, element, name, value_type) \
58 int sd_rtnl_message_##class##_set_##name(sd_netlink_message *m, value_type value) { \
59 assert_return(m, -EINVAL); \
60 assert_return(m->hdr, -EINVAL); \
61 assert_return(rtnl_message_type_is_##class(m->hdr->nlmsg_type), -EINVAL); \
63 header_type *hdr = NLMSG_DATA(m->hdr); \
64 hdr->element = value; \
68 #define DEFINE_RTNL_MESSAGE_PREFIXLEN_SETTER(class, header_type, family_element, element, name, value_type) \
69 int sd_rtnl_message_##class##_set_##name(sd_netlink_message *m, value_type value) { \
70 assert_return(m, -EINVAL); \
71 assert_return(m->hdr, -EINVAL); \
72 assert_return(rtnl_message_type_is_##class(m->hdr->nlmsg_type), -EINVAL); \
74 header_type *hdr = NLMSG_DATA(m->hdr); \
76 if (value > FAMILY_ADDRESS_SIZE_SAFE(hdr->family_element) * 8) \
79 hdr->element = value; \
83 #define DEFINE_RTNL_MESSAGE_ADDR_SETTER(element, name, value_type) \
84 DEFINE_RTNL_MESSAGE_SETTER(addr, struct ifaddrmsg, element, name, value_type)
85 #define DEFINE_RTNL_MESSAGE_LINK_SETTER(element, name, value_type) \
86 DEFINE_RTNL_MESSAGE_SETTER(link, struct ifinfomsg, element, name, value_type)
87 #define DEFINE_RTNL_MESSAGE_ROUTE_SETTER(element, name, value_type) \
88 DEFINE_RTNL_MESSAGE_SETTER(route, struct rtmsg, element, name, value_type)
89 #define DEFINE_RTNL_MESSAGE_NEXTHOP_SETTER(element, name, value_type) \
90 DEFINE_RTNL_MESSAGE_SETTER(nexthop, struct nhmsg, element, name, value_type)
91 #define DEFINE_RTNL_MESSAGE_NEIGH_SETTER(element, name, value_type) \
92 DEFINE_RTNL_MESSAGE_SETTER(neigh, struct ndmsg, element, name, value_type)
93 #define DEFINE_RTNL_MESSAGE_ADDRLABEL_SETTER(element, name, value_type) \
94 DEFINE_RTNL_MESSAGE_SETTER(addrlabel, struct ifaddrlblmsg, element, name, value_type)
95 #define DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_SETTER(element, name, value_type) \
96 DEFINE_RTNL_MESSAGE_SETTER(routing_policy_rule, struct fib_rule_hdr, element, name, value_type)
97 #define DEFINE_RTNL_MESSAGE_TRAFFIC_CONTROL_SETTER(element, name, value_type) \
98 DEFINE_RTNL_MESSAGE_SETTER(traffic_control, struct tcmsg, element, name, value_type)
100 #define DEFINE_RTNL_MESSAGE_GETTER(class, header_type, element, name, value_type) \
101 int sd_rtnl_message_##class##_get_##name(sd_netlink_message *m, value_type *ret) { \
102 assert_return(m, -EINVAL); \
103 assert_return(m->hdr, -EINVAL); \
104 assert_return(rtnl_message_type_is_##class(m->hdr->nlmsg_type), -EINVAL); \
105 assert_return(ret, -EINVAL); \
107 header_type *hdr = NLMSG_DATA(m->hdr); \
108 *ret = hdr->element; \
112 #define DEFINE_RTNL_MESSAGE_ADDR_GETTER(element, name, value_type) \
113 DEFINE_RTNL_MESSAGE_GETTER(addr, struct ifaddrmsg, element, name, value_type)
114 #define DEFINE_RTNL_MESSAGE_LINK_GETTER(element, name, value_type) \
115 DEFINE_RTNL_MESSAGE_GETTER(link, struct ifinfomsg, element, name, value_type)
116 #define DEFINE_RTNL_MESSAGE_ROUTE_GETTER(element, name, value_type) \
117 DEFINE_RTNL_MESSAGE_GETTER(route, struct rtmsg, element, name, value_type)
118 #define DEFINE_RTNL_MESSAGE_NEXTHOP_GETTER(element, name, value_type) \
119 DEFINE_RTNL_MESSAGE_GETTER(nexthop, struct nhmsg, element, name, value_type)
120 #define DEFINE_RTNL_MESSAGE_NEIGH_GETTER(element, name, value_type) \
121 DEFINE_RTNL_MESSAGE_GETTER(neigh, struct ndmsg, element, name, value_type)
122 #define DEFINE_RTNL_MESSAGE_ADDRLABEL_GETTER(element, name, value_type) \
123 DEFINE_RTNL_MESSAGE_GETTER(addrlabel, struct ifaddrlblmsg, element, name, value_type)
124 #define DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(element, name, value_type) \
125 DEFINE_RTNL_MESSAGE_GETTER(routing_policy_rule, struct fib_rule_hdr, element, name, value_type)
126 #define DEFINE_RTNL_MESSAGE_TRAFFIC_CONTROL_GETTER(element, name, value_type) \
127 DEFINE_RTNL_MESSAGE_GETTER(traffic_control, struct tcmsg, element, name, value_type)
129 DEFINE_RTNL_MESSAGE_ADDR_GETTER(ifa_index
, ifindex
, int);
130 DEFINE_RTNL_MESSAGE_ADDR_GETTER(ifa_family
, family
, int);
131 DEFINE_RTNL_MESSAGE_PREFIXLEN_SETTER(addr
, struct ifaddrmsg
, ifa_family
, ifa_prefixlen
, prefixlen
, uint8_t);
132 DEFINE_RTNL_MESSAGE_ADDR_GETTER(ifa_prefixlen
, prefixlen
, uint8_t);
133 DEFINE_RTNL_MESSAGE_ADDR_SETTER(ifa_scope
, scope
, uint8_t);
134 DEFINE_RTNL_MESSAGE_ADDR_GETTER(ifa_scope
, scope
, uint8_t);
136 DEFINE_RTNL_MESSAGE_LINK_GETTER(ifi_index
, ifindex
, int);
137 DEFINE_RTNL_MESSAGE_LINK_SETTER(ifi_family
, family
, int);
138 DEFINE_RTNL_MESSAGE_LINK_GETTER(ifi_family
, family
, int);
139 DEFINE_RTNL_MESSAGE_LINK_SETTER(ifi_type
, type
, uint16_t);
140 DEFINE_RTNL_MESSAGE_LINK_GETTER(ifi_type
, type
, uint16_t);
141 DEFINE_RTNL_MESSAGE_LINK_GETTER(ifi_flags
, flags
, uint32_t);
143 int sd_rtnl_message_link_set_flags(sd_netlink_message
*m
, uint32_t flags
, uint32_t change
) {
144 struct ifinfomsg
*ifi
;
146 assert_return(m
, -EINVAL
);
147 assert_return(m
->hdr
, -EINVAL
);
148 assert_return(rtnl_message_type_is_link(m
->hdr
->nlmsg_type
), -EINVAL
);
149 assert_return(change
!= 0, -EINVAL
);
151 ifi
= NLMSG_DATA(m
->hdr
);
153 ifi
->ifi_flags
= flags
;
154 ifi
->ifi_change
= change
;
159 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_family
, family
, int);
160 DEFINE_RTNL_MESSAGE_PREFIXLEN_SETTER(route
, struct rtmsg
, rtm_family
, rtm_dst_len
, dst_prefixlen
, uint8_t);
161 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_dst_len
, dst_prefixlen
, uint8_t);
162 DEFINE_RTNL_MESSAGE_PREFIXLEN_SETTER(route
, struct rtmsg
, rtm_family
, rtm_src_len
, src_prefixlen
, uint8_t);
163 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_src_len
, src_prefixlen
, uint8_t);
164 DEFINE_RTNL_MESSAGE_ROUTE_SETTER(rtm_tos
, tos
, uint8_t);
165 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_tos
, tos
, uint8_t);
166 DEFINE_RTNL_MESSAGE_ROUTE_SETTER(rtm_table
, table
, uint8_t);
167 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_table
, table
, uint8_t);
168 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_protocol
, protocol
, uint8_t);
169 DEFINE_RTNL_MESSAGE_ROUTE_SETTER(rtm_scope
, scope
, uint8_t);
170 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_scope
, scope
, uint8_t);
171 DEFINE_RTNL_MESSAGE_ROUTE_SETTER(rtm_type
, type
, uint8_t);
172 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_type
, type
, uint8_t);
173 DEFINE_RTNL_MESSAGE_ROUTE_SETTER(rtm_flags
, flags
, uint32_t);
174 DEFINE_RTNL_MESSAGE_ROUTE_GETTER(rtm_flags
, flags
, uint32_t);
176 DEFINE_RTNL_MESSAGE_NEXTHOP_GETTER(nh_family
, family
, int);
177 DEFINE_RTNL_MESSAGE_NEXTHOP_SETTER(nh_flags
, flags
, uint32_t);
178 DEFINE_RTNL_MESSAGE_NEXTHOP_GETTER(nh_flags
, flags
, uint32_t);
179 DEFINE_RTNL_MESSAGE_NEXTHOP_GETTER(nh_protocol
, protocol
, uint8_t);
181 DEFINE_RTNL_MESSAGE_NEIGH_GETTER(ndm_ifindex
, ifindex
, int);
182 DEFINE_RTNL_MESSAGE_NEIGH_GETTER(ndm_family
, family
, int);
183 DEFINE_RTNL_MESSAGE_NEIGH_SETTER(ndm_state
, state
, uint16_t);
184 DEFINE_RTNL_MESSAGE_NEIGH_GETTER(ndm_state
, state
, uint16_t);
185 DEFINE_RTNL_MESSAGE_NEIGH_SETTER(ndm_flags
, flags
, uint8_t);
186 DEFINE_RTNL_MESSAGE_NEIGH_GETTER(ndm_flags
, flags
, uint8_t);
188 DEFINE_RTNL_MESSAGE_ADDRLABEL_GETTER(ifal_prefixlen
, prefixlen
, uint8_t);
190 int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message
*m
, uint8_t prefixlen
) {
191 struct ifaddrlblmsg
*addrlabel
;
193 assert_return(m
, -EINVAL
);
194 assert_return(m
->hdr
, -EINVAL
);
195 assert_return(rtnl_message_type_is_addrlabel(m
->hdr
->nlmsg_type
), -EINVAL
);
197 addrlabel
= NLMSG_DATA(m
->hdr
);
202 addrlabel
->ifal_prefixlen
= prefixlen
;
207 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(family
, family
, int);
208 DEFINE_RTNL_MESSAGE_PREFIXLEN_SETTER(routing_policy_rule
, struct fib_rule_hdr
, family
, dst_len
, dst_prefixlen
, uint8_t);
209 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(dst_len
, dst_prefixlen
, uint8_t);
210 DEFINE_RTNL_MESSAGE_PREFIXLEN_SETTER(routing_policy_rule
, struct fib_rule_hdr
, family
, src_len
, src_prefixlen
, uint8_t);
211 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(src_len
, src_prefixlen
, uint8_t);
212 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_SETTER(tos
, tos
, uint8_t);
213 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(tos
, tos
, uint8_t);
214 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_SETTER(table
, table
, uint8_t);
215 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(table
, table
, uint8_t);
216 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_SETTER(action
, action
, uint8_t);
217 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(action
, action
, uint8_t);
218 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_SETTER(flags
, flags
, uint32_t);
219 DEFINE_RTNL_MESSAGE_ROUTING_POLICY_RULE_GETTER(flags
, flags
, uint32_t);
221 DEFINE_RTNL_MESSAGE_TRAFFIC_CONTROL_GETTER(tcm_ifindex
, ifindex
, int);
222 DEFINE_RTNL_MESSAGE_TRAFFIC_CONTROL_GETTER(tcm_handle
, handle
, uint32_t);
223 DEFINE_RTNL_MESSAGE_TRAFFIC_CONTROL_GETTER(tcm_parent
, parent
, uint32_t);
225 int sd_rtnl_message_new_route(
227 sd_netlink_message
**ret
,
235 assert_return(rtnl_message_type_is_route(nlmsg_type
), -EINVAL
);
236 assert_return((nlmsg_type
== RTM_GETROUTE
&& family
== AF_UNSPEC
) ||
237 IN_SET(family
, AF_INET
, AF_INET6
), -EINVAL
);
238 assert_return(ret
, -EINVAL
);
240 r
= message_new(rtnl
,
243 NLM_F_REQUEST
|NLM_F_ACK
|(nlmsg_type
== RTM_NEWROUTE
? NLM_F_CREATE
| NLM_F_APPEND
: 0));
247 rtm
= NLMSG_DATA((*ret
)->hdr
);
249 rtm
->rtm_family
= family
;
250 rtm
->rtm_protocol
= protocol
;
255 int sd_rtnl_message_new_nexthop(sd_netlink
*rtnl
, sd_netlink_message
**ret
,
256 uint16_t nlmsg_type
, int family
,
261 assert_return(rtnl_message_type_is_nexthop(nlmsg_type
), -EINVAL
);
262 switch (nlmsg_type
) {
264 assert_return(family
== AF_UNSPEC
, -EINVAL
);
267 assert_return(protocol
== RTPROT_UNSPEC
, -EINVAL
);
270 assert_return(IN_SET(family
, AF_UNSPEC
, AF_INET
, AF_INET6
), -EINVAL
);
273 assert_not_reached();
275 assert_return(ret
, -EINVAL
);
277 r
= message_new(rtnl
,
280 NLM_F_REQUEST
| NLM_F_ACK
| (nlmsg_type
== RTM_NEWNEXTHOP
? NLM_F_CREATE
| NLM_F_REPLACE
: 0));
284 nhm
= NLMSG_DATA((*ret
)->hdr
);
286 nhm
->nh_family
= family
;
287 nhm
->nh_scope
= RT_SCOPE_UNIVERSE
;
288 nhm
->nh_protocol
= protocol
;
293 int sd_rtnl_message_new_neigh(
295 sd_netlink_message
**ret
,
303 assert_return(rtnl_message_type_is_neigh(nlmsg_type
), -EINVAL
);
304 assert_return(IN_SET(family
, AF_UNSPEC
, AF_INET
, AF_INET6
, AF_BRIDGE
), -EINVAL
);
305 assert_return(ret
, -EINVAL
);
307 uint16_t flags
= NLM_F_REQUEST
| NLM_F_ACK
;
308 if (nlmsg_type
== RTM_NEWNEIGH
) {
309 if (family
== AF_BRIDGE
)
310 flags
|= NLM_F_CREATE
| NLM_F_APPEND
;
312 flags
|= NLM_F_CREATE
| NLM_F_REPLACE
;
315 r
= message_new(rtnl
, ret
, nlmsg_type
, flags
);
319 ndm
= NLMSG_DATA((*ret
)->hdr
);
321 ndm
->ndm_family
= family
;
322 ndm
->ndm_ifindex
= ifindex
;
327 int sd_rtnl_message_new_link(sd_netlink
*rtnl
, sd_netlink_message
**ret
, uint16_t nlmsg_type
, int ifindex
) {
328 struct ifinfomsg
*ifi
;
331 assert_return(rtnl_message_type_is_link(nlmsg_type
), -EINVAL
);
332 assert_return(ret
, -EINVAL
);
334 uint16_t flags
= NLM_F_REQUEST
| NLM_F_ACK
;
335 if (nlmsg_type
== RTM_NEWLINK
&& ifindex
== 0)
336 flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
337 else if (nlmsg_type
== RTM_NEWLINKPROP
)
338 flags
|= NLM_F_CREATE
| NLM_F_EXCL
| NLM_F_APPEND
;
340 r
= message_new(rtnl
, ret
, nlmsg_type
, flags
);
344 ifi
= NLMSG_DATA((*ret
)->hdr
);
346 ifi
->ifi_family
= AF_UNSPEC
;
347 ifi
->ifi_index
= ifindex
;
352 int sd_rtnl_message_new_addr(
354 sd_netlink_message
**ret
,
359 struct ifaddrmsg
*ifa
;
362 assert_return(rtnl_message_type_is_addr(nlmsg_type
), -EINVAL
);
363 assert_return((nlmsg_type
== RTM_GETADDR
&& ifindex
== 0) ||
364 ifindex
> 0, -EINVAL
);
365 assert_return((nlmsg_type
== RTM_GETADDR
&& family
== AF_UNSPEC
) ||
366 IN_SET(family
, AF_INET
, AF_INET6
), -EINVAL
);
367 assert_return(ret
, -EINVAL
);
369 r
= message_new(rtnl
, ret
, nlmsg_type
, NLM_F_REQUEST
| NLM_F_ACK
);
373 ifa
= NLMSG_DATA((*ret
)->hdr
);
375 ifa
->ifa_index
= ifindex
;
376 ifa
->ifa_family
= family
;
381 int sd_rtnl_message_new_addr_update(
383 sd_netlink_message
**ret
,
388 r
= sd_rtnl_message_new_addr(rtnl
, ret
, RTM_NEWADDR
, ifindex
, family
);
392 (*ret
)->hdr
->nlmsg_flags
|= NLM_F_REPLACE
;
397 int sd_rtnl_message_get_family(sd_netlink_message
*m
, int *ret
) {
398 assert_return(m
, -EINVAL
);
399 assert_return(ret
, -EINVAL
);
403 if (rtnl_message_type_is_link(m
->hdr
->nlmsg_type
))
404 return sd_rtnl_message_link_get_family(m
, ret
);
406 if (rtnl_message_type_is_route(m
->hdr
->nlmsg_type
))
407 return sd_rtnl_message_route_get_family(m
, ret
);
409 if (rtnl_message_type_is_neigh(m
->hdr
->nlmsg_type
))
410 return sd_rtnl_message_neigh_get_family(m
, ret
);
412 if (rtnl_message_type_is_addr(m
->hdr
->nlmsg_type
))
413 return sd_rtnl_message_addr_get_family(m
, ret
);
415 if (rtnl_message_type_is_routing_policy_rule(m
->hdr
->nlmsg_type
))
416 return sd_rtnl_message_routing_policy_rule_get_family(m
, ret
);
418 if (rtnl_message_type_is_nexthop(m
->hdr
->nlmsg_type
))
419 return sd_rtnl_message_nexthop_get_family(m
, ret
);
424 int sd_rtnl_message_new_addrlabel(
426 sd_netlink_message
**ret
,
431 struct ifaddrlblmsg
*addrlabel
;
434 assert_return(rtnl_message_type_is_addrlabel(nlmsg_type
), -EINVAL
);
435 assert_return(ret
, -EINVAL
);
437 r
= message_new(rtnl
,
440 NLM_F_REQUEST
| NLM_F_ACK
| (nlmsg_type
== RTM_NEWADDRLABEL
? NLM_F_CREATE
| NLM_F_REPLACE
: 0));
444 addrlabel
= NLMSG_DATA((*ret
)->hdr
);
446 addrlabel
->ifal_family
= family
;
447 addrlabel
->ifal_index
= ifindex
;
452 int sd_rtnl_message_new_routing_policy_rule(
454 sd_netlink_message
**ret
,
458 struct fib_rule_hdr
*frh
;
461 assert_return(rtnl_message_type_is_routing_policy_rule(nlmsg_type
), -EINVAL
);
462 assert_return(ret
, -EINVAL
);
464 r
= message_new(rtnl
,
467 NLM_F_REQUEST
| NLM_F_ACK
| (nlmsg_type
== RTM_NEWRULE
? NLM_F_CREATE
| NLM_F_EXCL
: 0));
471 frh
= NLMSG_DATA((*ret
)->hdr
);
472 frh
->family
= family
;
477 int sd_rtnl_message_new_traffic_control(
479 sd_netlink_message
**ret
,
488 assert_return(rtnl_message_type_is_traffic_control(nlmsg_type
), -EINVAL
);
489 assert_return(ret
, -EINVAL
);
491 r
= message_new(rtnl
,
494 NLM_F_REQUEST
| NLM_F_ACK
| (IN_SET(nlmsg_type
, RTM_NEWQDISC
, RTM_NEWTCLASS
) ? NLM_F_CREATE
| NLM_F_REPLACE
: 0));
498 tcm
= NLMSG_DATA((*ret
)->hdr
);
499 tcm
->tcm_ifindex
= ifindex
;
500 tcm
->tcm_handle
= handle
;
501 tcm
->tcm_parent
= parent
;
506 int sd_rtnl_message_new_mdb(
508 sd_netlink_message
**ret
,
512 struct br_port_msg
*bpm
;
515 assert_return(rtnl_message_type_is_mdb(nlmsg_type
), -EINVAL
);
516 assert_return(ret
, -EINVAL
);
518 r
= message_new(rtnl
,
521 NLM_F_REQUEST
| NLM_F_ACK
| (nlmsg_type
== RTM_NEWMDB
? NLM_F_CREATE
| NLM_F_REPLACE
: 0));
525 bpm
= NLMSG_DATA((*ret
)->hdr
);
526 bpm
->family
= AF_BRIDGE
;
527 bpm
->ifindex
= ifindex
;
532 int sd_rtnl_message_new_nsid(
534 sd_netlink_message
**ret
,
535 uint16_t nlmsg_type
) {
540 assert_return(rtnl_message_type_is_nsid(nlmsg_type
), -EINVAL
);
541 assert_return(ret
, -EINVAL
);
543 r
= message_new(rtnl
, ret
, nlmsg_type
, NLM_F_REQUEST
| NLM_F_ACK
);
547 rt
= NLMSG_DATA((*ret
)->hdr
);
548 rt
->rtgen_family
= AF_UNSPEC
;