]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
89489ef7 TG |
2 | |
3 | #include <netinet/in.h> | |
30746d60 | 4 | #include <linux/if_addrlabel.h> |
1903c9bb | 5 | #include <linux/if_bridge.h> |
c16c7808 | 6 | #include <linux/nexthop.h> |
89489ef7 TG |
7 | #include <stdbool.h> |
8 | #include <unistd.h> | |
9 | ||
07630cea LP |
10 | #include "sd-netlink.h" |
11 | ||
f97b34a6 | 12 | #include "format-util.h" |
89489ef7 TG |
13 | #include "netlink-internal.h" |
14 | #include "netlink-types.h" | |
07630cea | 15 | #include "netlink-util.h" |
07630cea LP |
16 | #include "socket-util.h" |
17 | #include "util.h" | |
89489ef7 TG |
18 | |
19 | int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message *m, unsigned char prefixlen) { | |
20 | struct rtmsg *rtm; | |
21 | ||
22 | assert_return(m, -EINVAL); | |
23 | assert_return(m->hdr, -EINVAL); | |
24 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
25 | ||
26 | rtm = NLMSG_DATA(m->hdr); | |
27 | ||
28 | if ((rtm->rtm_family == AF_INET && prefixlen > 32) || | |
29 | (rtm->rtm_family == AF_INET6 && prefixlen > 128)) | |
30 | return -ERANGE; | |
31 | ||
32 | rtm->rtm_dst_len = prefixlen; | |
33 | ||
34 | return 0; | |
35 | } | |
36 | ||
37 | int sd_rtnl_message_route_set_src_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_src_len = prefixlen; | |
51 | ||
52 | return 0; | |
53 | } | |
54 | ||
55 | int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope) { | |
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 | rtm->rtm_scope = scope; | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
6b9e85a7 TG |
69 | int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags) { |
70 | struct rtmsg *rtm; | |
71 | ||
72 | assert_return(m, -EINVAL); | |
73 | assert_return(m->hdr, -EINVAL); | |
74 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
75 | ||
76 | rtm = NLMSG_DATA(m->hdr); | |
77 | ||
78 | rtm->rtm_flags = flags; | |
79 | ||
80 | return 0; | |
81 | } | |
82 | ||
de157fe2 | 83 | int sd_rtnl_message_route_get_flags(const sd_netlink_message *m, unsigned *flags) { |
6b9e85a7 TG |
84 | struct rtmsg *rtm; |
85 | ||
86 | assert_return(m, -EINVAL); | |
87 | assert_return(m->hdr, -EINVAL); | |
88 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
89 | assert_return(flags, -EINVAL); | |
90 | ||
91 | rtm = NLMSG_DATA(m->hdr); | |
92 | ||
93 | *flags = rtm->rtm_flags; | |
94 | ||
95 | return 0; | |
96 | } | |
97 | ||
ec1bb279 SS |
98 | int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table) { |
99 | struct rtmsg *rtm; | |
100 | ||
101 | assert_return(m, -EINVAL); | |
102 | assert_return(m->hdr, -EINVAL); | |
103 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
104 | ||
105 | rtm = NLMSG_DATA(m->hdr); | |
106 | ||
107 | rtm->rtm_table = table; | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
de157fe2 | 112 | int sd_rtnl_message_route_get_family(const sd_netlink_message *m, int *family) { |
89489ef7 TG |
113 | struct rtmsg *rtm; |
114 | ||
115 | assert_return(m, -EINVAL); | |
116 | assert_return(m->hdr, -EINVAL); | |
117 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
118 | assert_return(family, -EINVAL); | |
119 | ||
120 | rtm = NLMSG_DATA(m->hdr); | |
121 | ||
122 | *family = rtm->rtm_family; | |
123 | ||
124 | return 0; | |
125 | } | |
126 | ||
ec1bb279 SS |
127 | int sd_rtnl_message_route_set_family(sd_netlink_message *m, int family) { |
128 | struct rtmsg *rtm; | |
129 | ||
130 | assert_return(m, -EINVAL); | |
131 | assert_return(m->hdr, -EINVAL); | |
132 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
133 | ||
134 | rtm = NLMSG_DATA(m->hdr); | |
135 | ||
136 | rtm->rtm_family = family; | |
137 | ||
138 | return 0; | |
139 | } | |
140 | ||
de157fe2 | 141 | int sd_rtnl_message_route_get_type(const sd_netlink_message *m, unsigned char *type) { |
983226f3 SS |
142 | struct rtmsg *rtm; |
143 | ||
144 | assert_return(m, -EINVAL); | |
145 | assert_return(m->hdr, -EINVAL); | |
146 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
147 | assert_return(type, -EINVAL); | |
148 | ||
149 | rtm = NLMSG_DATA(m->hdr); | |
150 | ||
151 | *type = rtm->rtm_type; | |
152 | ||
153 | return 0; | |
154 | } | |
155 | ||
156 | int sd_rtnl_message_route_set_type(sd_netlink_message *m, unsigned char type) { | |
157 | struct rtmsg *rtm; | |
158 | ||
159 | assert_return(m, -EINVAL); | |
160 | assert_return(m->hdr, -EINVAL); | |
161 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
162 | ||
163 | rtm = NLMSG_DATA(m->hdr); | |
164 | ||
165 | rtm->rtm_type = type; | |
166 | ||
167 | return 0; | |
168 | } | |
169 | ||
de157fe2 | 170 | int sd_rtnl_message_route_get_protocol(const sd_netlink_message *m, unsigned char *protocol) { |
ad70f789 TG |
171 | struct rtmsg *rtm; |
172 | ||
173 | assert_return(m, -EINVAL); | |
174 | assert_return(m->hdr, -EINVAL); | |
175 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
176 | assert_return(protocol, -EINVAL); | |
177 | ||
178 | rtm = NLMSG_DATA(m->hdr); | |
179 | ||
180 | *protocol = rtm->rtm_protocol; | |
181 | ||
182 | return 0; | |
183 | } | |
184 | ||
de157fe2 | 185 | int sd_rtnl_message_route_get_scope(const sd_netlink_message *m, unsigned char *scope) { |
ad70f789 TG |
186 | struct rtmsg *rtm; |
187 | ||
188 | assert_return(m, -EINVAL); | |
189 | assert_return(m->hdr, -EINVAL); | |
190 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
191 | assert_return(scope, -EINVAL); | |
192 | ||
193 | rtm = NLMSG_DATA(m->hdr); | |
194 | ||
195 | *scope = rtm->rtm_scope; | |
196 | ||
197 | return 0; | |
198 | } | |
199 | ||
de157fe2 | 200 | int sd_rtnl_message_route_get_tos(const sd_netlink_message *m, unsigned char *tos) { |
ad70f789 TG |
201 | struct rtmsg *rtm; |
202 | ||
203 | assert_return(m, -EINVAL); | |
204 | assert_return(m->hdr, -EINVAL); | |
205 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
206 | assert_return(tos, -EINVAL); | |
207 | ||
208 | rtm = NLMSG_DATA(m->hdr); | |
209 | ||
210 | *tos = rtm->rtm_tos; | |
211 | ||
212 | return 0; | |
213 | } | |
214 | ||
de157fe2 | 215 | int sd_rtnl_message_route_get_table(const sd_netlink_message *m, unsigned char *table) { |
ad70f789 TG |
216 | struct rtmsg *rtm; |
217 | ||
218 | assert_return(m, -EINVAL); | |
219 | assert_return(m->hdr, -EINVAL); | |
220 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
221 | assert_return(table, -EINVAL); | |
222 | ||
223 | rtm = NLMSG_DATA(m->hdr); | |
224 | ||
225 | *table = rtm->rtm_table; | |
226 | ||
227 | return 0; | |
228 | } | |
229 | ||
de157fe2 | 230 | int sd_rtnl_message_route_get_dst_prefixlen(const sd_netlink_message *m, unsigned char *dst_len) { |
89489ef7 TG |
231 | struct rtmsg *rtm; |
232 | ||
233 | assert_return(m, -EINVAL); | |
234 | assert_return(m->hdr, -EINVAL); | |
235 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
236 | assert_return(dst_len, -EINVAL); | |
237 | ||
238 | rtm = NLMSG_DATA(m->hdr); | |
239 | ||
240 | *dst_len = rtm->rtm_dst_len; | |
241 | ||
242 | return 0; | |
243 | } | |
244 | ||
de157fe2 | 245 | int sd_rtnl_message_route_get_src_prefixlen(const sd_netlink_message *m, unsigned char *src_len) { |
89489ef7 TG |
246 | struct rtmsg *rtm; |
247 | ||
248 | assert_return(m, -EINVAL); | |
249 | assert_return(m->hdr, -EINVAL); | |
250 | assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); | |
251 | assert_return(src_len, -EINVAL); | |
252 | ||
253 | rtm = NLMSG_DATA(m->hdr); | |
254 | ||
255 | *src_len = rtm->rtm_src_len; | |
256 | ||
257 | return 0; | |
258 | } | |
259 | ||
260 | int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret, | |
261 | uint16_t nlmsg_type, int rtm_family, | |
262 | unsigned char rtm_protocol) { | |
263 | struct rtmsg *rtm; | |
264 | int r; | |
265 | ||
266 | assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL); | |
267 | assert_return((nlmsg_type == RTM_GETROUTE && rtm_family == AF_UNSPEC) || | |
945c2931 | 268 | IN_SET(rtm_family, AF_INET, AF_INET6), -EINVAL); |
89489ef7 TG |
269 | assert_return(ret, -EINVAL); |
270 | ||
271 | r = message_new(rtnl, ret, nlmsg_type); | |
272 | if (r < 0) | |
273 | return r; | |
274 | ||
275 | if (nlmsg_type == RTM_NEWROUTE) | |
276 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; | |
277 | ||
278 | rtm = NLMSG_DATA((*ret)->hdr); | |
279 | ||
280 | rtm->rtm_family = rtm_family; | |
281 | rtm->rtm_scope = RT_SCOPE_UNIVERSE; | |
282 | rtm->rtm_type = RTN_UNICAST; | |
283 | rtm->rtm_table = RT_TABLE_MAIN; | |
284 | rtm->rtm_protocol = rtm_protocol; | |
285 | ||
286 | return 0; | |
287 | } | |
288 | ||
c16c7808 SS |
289 | int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, |
290 | uint16_t nhmsg_type, int nh_family, | |
291 | unsigned char nh_protocol) { | |
292 | struct nhmsg *nhm; | |
293 | int r; | |
294 | ||
295 | assert_return(rtnl_message_type_is_nexthop(nhmsg_type), -EINVAL); | |
296 | assert_return((nhmsg_type == RTM_GETNEXTHOP && nh_family == AF_UNSPEC) || | |
297 | IN_SET(nh_family, AF_INET, AF_INET6), -EINVAL); | |
298 | assert_return(ret, -EINVAL); | |
299 | ||
300 | r = message_new(rtnl, ret, nhmsg_type); | |
301 | if (r < 0) | |
302 | return r; | |
303 | ||
304 | if (nhmsg_type == RTM_NEWNEXTHOP) | |
305 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; | |
306 | ||
307 | nhm = NLMSG_DATA((*ret)->hdr); | |
308 | ||
309 | nhm->nh_family = nh_family; | |
310 | nhm->nh_scope = RT_SCOPE_UNIVERSE; | |
311 | nhm->nh_protocol = nh_protocol; | |
312 | ||
313 | return 0; | |
314 | } | |
315 | ||
316 | int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags) { | |
317 | struct nhmsg *nhm; | |
318 | ||
319 | assert_return(m, -EINVAL); | |
320 | assert_return(m->hdr, -EINVAL); | |
321 | assert_return(rtnl_message_type_is_nexthop(m->hdr->nlmsg_type), -EINVAL); | |
322 | ||
323 | nhm = NLMSG_DATA(m->hdr); | |
324 | nhm->nh_flags |= flags; | |
325 | ||
326 | return 0; | |
327 | } | |
328 | ||
329 | int sd_rtnl_message_nexthop_set_family(sd_netlink_message *m, uint8_t family) { | |
330 | struct nhmsg *nhm; | |
331 | ||
332 | assert_return(m, -EINVAL); | |
333 | assert_return(m->hdr, -EINVAL); | |
334 | ||
335 | nhm = NLMSG_DATA(m->hdr); | |
336 | nhm->nh_family = family; | |
337 | ||
338 | return 0; | |
339 | } | |
340 | ||
de157fe2 | 341 | int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *family) { |
c16c7808 SS |
342 | struct nhmsg *nhm; |
343 | ||
344 | assert_return(m, -EINVAL); | |
345 | assert_return(m->hdr, -EINVAL); | |
346 | ||
347 | nhm = NLMSG_DATA(m->hdr); | |
348 | *family = nhm->nh_family ; | |
349 | ||
350 | return 0; | |
351 | } | |
352 | ||
89489ef7 TG |
353 | int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) { |
354 | struct ndmsg *ndm; | |
355 | ||
356 | assert_return(m, -EINVAL); | |
357 | assert_return(m->hdr, -EINVAL); | |
358 | assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL); | |
359 | ||
360 | ndm = NLMSG_DATA(m->hdr); | |
361 | ndm->ndm_flags |= flags; | |
362 | ||
363 | return 0; | |
364 | } | |
365 | ||
366 | int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state) { | |
367 | struct ndmsg *ndm; | |
368 | ||
369 | assert_return(m, -EINVAL); | |
370 | assert_return(m->hdr, -EINVAL); | |
371 | assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL); | |
372 | ||
373 | ndm = NLMSG_DATA(m->hdr); | |
374 | ndm->ndm_state |= state; | |
375 | ||
376 | return 0; | |
377 | } | |
378 | ||
de157fe2 | 379 | int sd_rtnl_message_neigh_get_flags(const sd_netlink_message *m, uint8_t *flags) { |
89489ef7 TG |
380 | struct ndmsg *ndm; |
381 | ||
382 | assert_return(m, -EINVAL); | |
383 | assert_return(m->hdr, -EINVAL); | |
384 | assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL); | |
385 | ||
386 | ndm = NLMSG_DATA(m->hdr); | |
387 | *flags = ndm->ndm_flags; | |
388 | ||
389 | return 0; | |
390 | } | |
391 | ||
de157fe2 | 392 | int sd_rtnl_message_neigh_get_state(const sd_netlink_message *m, uint16_t *state) { |
89489ef7 TG |
393 | struct ndmsg *ndm; |
394 | ||
395 | assert_return(m, -EINVAL); | |
396 | assert_return(m->hdr, -EINVAL); | |
397 | assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL); | |
398 | ||
399 | ndm = NLMSG_DATA(m->hdr); | |
400 | *state = ndm->ndm_state; | |
401 | ||
402 | return 0; | |
403 | } | |
404 | ||
de157fe2 | 405 | int sd_rtnl_message_neigh_get_family(const sd_netlink_message *m, int *family) { |
89489ef7 TG |
406 | struct ndmsg *ndm; |
407 | ||
408 | assert_return(m, -EINVAL); | |
409 | assert_return(m->hdr, -EINVAL); | |
410 | assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL); | |
411 | assert_return(family, -EINVAL); | |
412 | ||
413 | ndm = NLMSG_DATA(m->hdr); | |
414 | ||
415 | *family = ndm->ndm_family; | |
416 | ||
417 | return 0; | |
418 | } | |
419 | ||
de157fe2 | 420 | int sd_rtnl_message_neigh_get_ifindex(const sd_netlink_message *m, int *index) { |
89489ef7 TG |
421 | struct ndmsg *ndm; |
422 | ||
423 | assert_return(m, -EINVAL); | |
424 | assert_return(m->hdr, -EINVAL); | |
425 | assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL); | |
426 | assert_return(index, -EINVAL); | |
427 | ||
428 | ndm = NLMSG_DATA(m->hdr); | |
429 | ||
430 | *index = ndm->ndm_ifindex; | |
431 | ||
432 | return 0; | |
433 | } | |
434 | ||
435 | int sd_rtnl_message_new_neigh(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int index, int ndm_family) { | |
436 | struct ndmsg *ndm; | |
437 | int r; | |
438 | ||
439 | assert_return(rtnl_message_type_is_neigh(nlmsg_type), -EINVAL); | |
40eb1b0a | 440 | assert_return(IN_SET(ndm_family, AF_UNSPEC, AF_INET, AF_INET6, AF_BRIDGE), -EINVAL); |
89489ef7 TG |
441 | assert_return(ret, -EINVAL); |
442 | ||
443 | r = message_new(rtnl, ret, nlmsg_type); | |
444 | if (r < 0) | |
445 | return r; | |
446 | ||
447 | if (nlmsg_type == RTM_NEWNEIGH) | |
448 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; | |
449 | ||
450 | ndm = NLMSG_DATA((*ret)->hdr); | |
451 | ||
452 | ndm->ndm_family = ndm_family; | |
453 | ndm->ndm_ifindex = index; | |
454 | ||
455 | return 0; | |
456 | } | |
457 | ||
458 | int sd_rtnl_message_link_set_flags(sd_netlink_message *m, unsigned flags, unsigned change) { | |
459 | struct ifinfomsg *ifi; | |
460 | ||
461 | assert_return(m, -EINVAL); | |
462 | assert_return(m->hdr, -EINVAL); | |
463 | assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); | |
464 | assert_return(change, -EINVAL); | |
465 | ||
466 | ifi = NLMSG_DATA(m->hdr); | |
467 | ||
468 | ifi->ifi_flags = flags; | |
469 | ifi->ifi_change = change; | |
470 | ||
471 | return 0; | |
472 | } | |
473 | ||
474 | int sd_rtnl_message_link_set_type(sd_netlink_message *m, unsigned type) { | |
475 | struct ifinfomsg *ifi; | |
476 | ||
477 | assert_return(m, -EINVAL); | |
478 | assert_return(m->hdr, -EINVAL); | |
479 | assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); | |
480 | ||
481 | ifi = NLMSG_DATA(m->hdr); | |
482 | ||
483 | ifi->ifi_type = type; | |
484 | ||
485 | return 0; | |
486 | } | |
487 | ||
488 | int sd_rtnl_message_link_set_family(sd_netlink_message *m, unsigned family) { | |
489 | struct ifinfomsg *ifi; | |
490 | ||
491 | assert_return(m, -EINVAL); | |
492 | assert_return(m->hdr, -EINVAL); | |
493 | assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); | |
494 | ||
495 | ifi = NLMSG_DATA(m->hdr); | |
496 | ||
497 | ifi->ifi_family = family; | |
498 | ||
499 | return 0; | |
500 | } | |
501 | ||
502 | int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret, | |
503 | uint16_t nlmsg_type, int index) { | |
504 | struct ifinfomsg *ifi; | |
505 | int r; | |
506 | ||
507 | assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL); | |
89489ef7 TG |
508 | assert_return(ret, -EINVAL); |
509 | ||
510 | r = message_new(rtnl, ret, nlmsg_type); | |
511 | if (r < 0) | |
512 | return r; | |
513 | ||
514 | if (nlmsg_type == RTM_NEWLINK) | |
515 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; | |
a26c3073 YW |
516 | else if (nlmsg_type == RTM_NEWLINKPROP) |
517 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL | NLM_F_APPEND; | |
89489ef7 TG |
518 | |
519 | ifi = NLMSG_DATA((*ret)->hdr); | |
520 | ||
521 | ifi->ifi_family = AF_UNSPEC; | |
522 | ifi->ifi_index = index; | |
523 | ||
524 | return 0; | |
525 | } | |
526 | ||
527 | int sd_rtnl_message_addr_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) { | |
528 | struct ifaddrmsg *ifa; | |
529 | ||
530 | assert_return(m, -EINVAL); | |
531 | assert_return(m->hdr, -EINVAL); | |
532 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
533 | ||
534 | ifa = NLMSG_DATA(m->hdr); | |
535 | ||
536 | if ((ifa->ifa_family == AF_INET && prefixlen > 32) || | |
537 | (ifa->ifa_family == AF_INET6 && prefixlen > 128)) | |
538 | return -ERANGE; | |
539 | ||
540 | ifa->ifa_prefixlen = prefixlen; | |
541 | ||
542 | return 0; | |
543 | } | |
544 | ||
545 | int sd_rtnl_message_addr_set_flags(sd_netlink_message *m, unsigned char flags) { | |
546 | struct ifaddrmsg *ifa; | |
547 | ||
548 | assert_return(m, -EINVAL); | |
549 | assert_return(m->hdr, -EINVAL); | |
550 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
551 | ||
552 | ifa = NLMSG_DATA(m->hdr); | |
553 | ||
554 | ifa->ifa_flags = flags; | |
555 | ||
556 | return 0; | |
557 | } | |
558 | ||
559 | int sd_rtnl_message_addr_set_scope(sd_netlink_message *m, unsigned char scope) { | |
560 | struct ifaddrmsg *ifa; | |
561 | ||
562 | assert_return(m, -EINVAL); | |
563 | assert_return(m->hdr, -EINVAL); | |
564 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
565 | ||
566 | ifa = NLMSG_DATA(m->hdr); | |
567 | ||
568 | ifa->ifa_scope = scope; | |
569 | ||
570 | return 0; | |
571 | } | |
572 | ||
de157fe2 | 573 | int sd_rtnl_message_addr_get_family(const sd_netlink_message *m, int *family) { |
89489ef7 TG |
574 | struct ifaddrmsg *ifa; |
575 | ||
576 | assert_return(m, -EINVAL); | |
577 | assert_return(m->hdr, -EINVAL); | |
578 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
579 | assert_return(family, -EINVAL); | |
580 | ||
581 | ifa = NLMSG_DATA(m->hdr); | |
582 | ||
583 | *family = ifa->ifa_family; | |
584 | ||
585 | return 0; | |
586 | } | |
587 | ||
de157fe2 | 588 | int sd_rtnl_message_addr_get_prefixlen(const sd_netlink_message *m, unsigned char *prefixlen) { |
89489ef7 TG |
589 | struct ifaddrmsg *ifa; |
590 | ||
591 | assert_return(m, -EINVAL); | |
592 | assert_return(m->hdr, -EINVAL); | |
593 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
594 | assert_return(prefixlen, -EINVAL); | |
595 | ||
596 | ifa = NLMSG_DATA(m->hdr); | |
597 | ||
598 | *prefixlen = ifa->ifa_prefixlen; | |
599 | ||
600 | return 0; | |
601 | } | |
602 | ||
de157fe2 | 603 | int sd_rtnl_message_addr_get_scope(const sd_netlink_message *m, unsigned char *scope) { |
89489ef7 TG |
604 | struct ifaddrmsg *ifa; |
605 | ||
606 | assert_return(m, -EINVAL); | |
607 | assert_return(m->hdr, -EINVAL); | |
608 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
609 | assert_return(scope, -EINVAL); | |
610 | ||
611 | ifa = NLMSG_DATA(m->hdr); | |
612 | ||
613 | *scope = ifa->ifa_scope; | |
614 | ||
615 | return 0; | |
616 | } | |
617 | ||
de157fe2 | 618 | int sd_rtnl_message_addr_get_flags(const sd_netlink_message *m, unsigned char *flags) { |
89489ef7 TG |
619 | struct ifaddrmsg *ifa; |
620 | ||
621 | assert_return(m, -EINVAL); | |
622 | assert_return(m->hdr, -EINVAL); | |
623 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
624 | assert_return(flags, -EINVAL); | |
625 | ||
626 | ifa = NLMSG_DATA(m->hdr); | |
627 | ||
628 | *flags = ifa->ifa_flags; | |
629 | ||
630 | return 0; | |
631 | } | |
632 | ||
de157fe2 | 633 | int sd_rtnl_message_addr_get_ifindex(const sd_netlink_message *m, int *ifindex) { |
89489ef7 TG |
634 | struct ifaddrmsg *ifa; |
635 | ||
636 | assert_return(m, -EINVAL); | |
637 | assert_return(m->hdr, -EINVAL); | |
638 | assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); | |
639 | assert_return(ifindex, -EINVAL); | |
640 | ||
641 | ifa = NLMSG_DATA(m->hdr); | |
642 | ||
643 | *ifindex = ifa->ifa_index; | |
644 | ||
645 | return 0; | |
646 | } | |
647 | ||
648 | int sd_rtnl_message_new_addr(sd_netlink *rtnl, sd_netlink_message **ret, | |
649 | uint16_t nlmsg_type, int index, | |
650 | int family) { | |
651 | struct ifaddrmsg *ifa; | |
652 | int r; | |
653 | ||
654 | assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL); | |
655 | assert_return((nlmsg_type == RTM_GETADDR && index == 0) || | |
656 | index > 0, -EINVAL); | |
657 | assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) || | |
945c2931 | 658 | IN_SET(family, AF_INET, AF_INET6), -EINVAL); |
89489ef7 TG |
659 | assert_return(ret, -EINVAL); |
660 | ||
661 | r = message_new(rtnl, ret, nlmsg_type); | |
662 | if (r < 0) | |
663 | return r; | |
664 | ||
665 | if (nlmsg_type == RTM_GETADDR) | |
666 | (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP; | |
667 | ||
668 | ifa = NLMSG_DATA((*ret)->hdr); | |
669 | ||
670 | ifa->ifa_index = index; | |
671 | ifa->ifa_family = family; | |
672 | if (family == AF_INET) | |
673 | ifa->ifa_prefixlen = 32; | |
674 | else if (family == AF_INET6) | |
675 | ifa->ifa_prefixlen = 128; | |
676 | ||
677 | return 0; | |
678 | } | |
679 | ||
680 | int sd_rtnl_message_new_addr_update(sd_netlink *rtnl, sd_netlink_message **ret, | |
681 | int index, int family) { | |
682 | int r; | |
683 | ||
684 | r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family); | |
685 | if (r < 0) | |
686 | return r; | |
687 | ||
688 | (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE; | |
689 | ||
690 | return 0; | |
691 | } | |
692 | ||
de157fe2 | 693 | int sd_rtnl_message_link_get_ifindex(const sd_netlink_message *m, int *ifindex) { |
89489ef7 TG |
694 | struct ifinfomsg *ifi; |
695 | ||
696 | assert_return(m, -EINVAL); | |
697 | assert_return(m->hdr, -EINVAL); | |
698 | assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); | |
699 | assert_return(ifindex, -EINVAL); | |
700 | ||
701 | ifi = NLMSG_DATA(m->hdr); | |
702 | ||
703 | *ifindex = ifi->ifi_index; | |
704 | ||
705 | return 0; | |
706 | } | |
707 | ||
de157fe2 | 708 | int sd_rtnl_message_link_get_flags(const sd_netlink_message *m, unsigned *flags) { |
89489ef7 TG |
709 | struct ifinfomsg *ifi; |
710 | ||
711 | assert_return(m, -EINVAL); | |
712 | assert_return(m->hdr, -EINVAL); | |
713 | assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); | |
714 | assert_return(flags, -EINVAL); | |
715 | ||
716 | ifi = NLMSG_DATA(m->hdr); | |
717 | ||
718 | *flags = ifi->ifi_flags; | |
719 | ||
720 | return 0; | |
721 | } | |
722 | ||
de157fe2 | 723 | int sd_rtnl_message_link_get_type(const sd_netlink_message *m, unsigned short *type) { |
89489ef7 TG |
724 | struct ifinfomsg *ifi; |
725 | ||
726 | assert_return(m, -EINVAL); | |
727 | assert_return(m->hdr, -EINVAL); | |
728 | assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); | |
729 | assert_return(type, -EINVAL); | |
730 | ||
731 | ifi = NLMSG_DATA(m->hdr); | |
732 | ||
733 | *type = ifi->ifi_type; | |
734 | ||
735 | return 0; | |
736 | } | |
737 | ||
de157fe2 | 738 | int sd_rtnl_message_get_family(const sd_netlink_message *m, int *family) { |
89489ef7 TG |
739 | assert_return(m, -EINVAL); |
740 | assert_return(family, -EINVAL); | |
741 | ||
742 | assert(m->hdr); | |
743 | ||
744 | if (rtnl_message_type_is_link(m->hdr->nlmsg_type)) { | |
745 | struct ifinfomsg *ifi; | |
746 | ||
747 | ifi = NLMSG_DATA(m->hdr); | |
748 | ||
749 | *family = ifi->ifi_family; | |
750 | ||
751 | return 0; | |
752 | } else if (rtnl_message_type_is_route(m->hdr->nlmsg_type)) { | |
753 | struct rtmsg *rtm; | |
754 | ||
755 | rtm = NLMSG_DATA(m->hdr); | |
756 | ||
757 | *family = rtm->rtm_family; | |
758 | ||
759 | return 0; | |
760 | } else if (rtnl_message_type_is_neigh(m->hdr->nlmsg_type)) { | |
761 | struct ndmsg *ndm; | |
762 | ||
763 | ndm = NLMSG_DATA(m->hdr); | |
764 | ||
765 | *family = ndm->ndm_family; | |
766 | ||
767 | return 0; | |
768 | } else if (rtnl_message_type_is_addr(m->hdr->nlmsg_type)) { | |
769 | struct ifaddrmsg *ifa; | |
770 | ||
771 | ifa = NLMSG_DATA(m->hdr); | |
772 | ||
773 | *family = ifa->ifa_family; | |
774 | ||
bce67bbe SS |
775 | return 0; |
776 | } else if (rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type)) { | |
777 | struct rtmsg *rtm; | |
778 | ||
779 | rtm = NLMSG_DATA(m->hdr); | |
780 | ||
781 | *family = rtm->rtm_family; | |
782 | ||
c16c7808 SS |
783 | return 0; |
784 | } else if (rtnl_message_type_is_nexthop(m->hdr->nlmsg_type)) { | |
785 | struct nhmsg *nhm; | |
786 | ||
787 | nhm = NLMSG_DATA(m->hdr); | |
788 | ||
789 | *family = nhm->nh_family; | |
790 | ||
89489ef7 TG |
791 | return 0; |
792 | } | |
793 | ||
794 | return -EOPNOTSUPP; | |
795 | } | |
30746d60 SS |
796 | |
797 | int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family) { | |
798 | struct ifaddrlblmsg *addrlabel; | |
799 | int r; | |
800 | ||
801 | assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL); | |
802 | assert_return(ret, -EINVAL); | |
803 | ||
804 | r = message_new(rtnl, ret, nlmsg_type); | |
805 | if (r < 0) | |
806 | return r; | |
807 | ||
808 | if (nlmsg_type == RTM_NEWADDRLABEL) | |
809 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; | |
810 | ||
811 | addrlabel = NLMSG_DATA((*ret)->hdr); | |
812 | ||
813 | addrlabel->ifal_family = ifal_family; | |
814 | addrlabel->ifal_index = ifindex; | |
815 | ||
816 | return 0; | |
817 | } | |
818 | ||
819 | int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) { | |
820 | struct ifaddrlblmsg *addrlabel; | |
821 | ||
822 | assert_return(m, -EINVAL); | |
823 | assert_return(m->hdr, -EINVAL); | |
824 | assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL); | |
825 | ||
826 | addrlabel = NLMSG_DATA(m->hdr); | |
827 | ||
828 | if (prefixlen > 128) | |
829 | return -ERANGE; | |
830 | ||
831 | addrlabel->ifal_prefixlen = prefixlen; | |
832 | ||
833 | return 0; | |
834 | } | |
d37b7627 | 835 | |
de157fe2 | 836 | int sd_rtnl_message_addrlabel_get_prefixlen(const sd_netlink_message *m, unsigned char *prefixlen) { |
d37b7627 SS |
837 | struct ifaddrlblmsg *addrlabel; |
838 | ||
839 | assert_return(m, -EINVAL); | |
840 | assert_return(m->hdr, -EINVAL); | |
841 | assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL); | |
842 | ||
843 | addrlabel = NLMSG_DATA(m->hdr); | |
844 | ||
845 | *prefixlen = addrlabel->ifal_prefixlen; | |
846 | ||
847 | return 0; | |
848 | } | |
bce67bbe SS |
849 | |
850 | int sd_rtnl_message_new_routing_policy_rule(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifal_family) { | |
851 | struct rtmsg *rtm; | |
852 | int r; | |
853 | ||
854 | assert_return(rtnl_message_type_is_routing_policy_rule(nlmsg_type), -EINVAL); | |
855 | assert_return(ret, -EINVAL); | |
856 | ||
857 | r = message_new(rtnl, ret, nlmsg_type); | |
858 | if (r < 0) | |
859 | return r; | |
860 | ||
861 | if (nlmsg_type == RTM_NEWRULE) | |
862 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; | |
863 | ||
864 | rtm = NLMSG_DATA((*ret)->hdr); | |
865 | rtm->rtm_family = ifal_family; | |
866 | rtm->rtm_protocol = RTPROT_BOOT; | |
867 | rtm->rtm_scope = RT_SCOPE_UNIVERSE; | |
868 | rtm->rtm_type = RTN_UNICAST; | |
869 | ||
870 | return 0; | |
871 | } | |
872 | ||
873 | int sd_rtnl_message_routing_policy_rule_set_tos(sd_netlink_message *m, unsigned char tos) { | |
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_tos = tos; | |
883 | ||
884 | return 0; | |
885 | } | |
886 | ||
de157fe2 | 887 | int sd_rtnl_message_routing_policy_rule_get_tos(const sd_netlink_message *m, unsigned char *tos) { |
bce67bbe SS |
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 | *tos = routing_policy_rule->rtm_tos; | |
897 | ||
898 | return 0; | |
899 | } | |
900 | ||
901 | int sd_rtnl_message_routing_policy_rule_set_table(sd_netlink_message *m, unsigned char table) { | |
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_table = table; | |
911 | ||
912 | return 0; | |
913 | } | |
914 | ||
de157fe2 | 915 | int sd_rtnl_message_routing_policy_rule_get_table(const sd_netlink_message *m, unsigned char *table) { |
bce67bbe SS |
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 | *table = routing_policy_rule->rtm_table; | |
925 | ||
926 | return 0; | |
927 | } | |
928 | ||
8b220643 SS |
929 | int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, unsigned flags) { |
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 | routing_policy_rule->rtm_flags |= flags; | |
938 | ||
939 | return 0; | |
940 | } | |
941 | ||
de157fe2 | 942 | int sd_rtnl_message_routing_policy_rule_get_flags(const sd_netlink_message *m, unsigned *flags) { |
8b220643 SS |
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 | *flags = routing_policy_rule->rtm_flags; | |
951 | ||
952 | return 0; | |
953 | } | |
954 | ||
bce67bbe SS |
955 | int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type) { |
956 | struct rtmsg *routing_policy_rule; | |
957 | ||
958 | assert_return(m, -EINVAL); | |
959 | assert_return(m->hdr, -EINVAL); | |
960 | assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); | |
961 | ||
962 | routing_policy_rule = NLMSG_DATA(m->hdr); | |
963 | ||
964 | routing_policy_rule->rtm_type = type; | |
965 | ||
966 | return 0; | |
967 | } | |
968 | ||
de157fe2 | 969 | int sd_rtnl_message_routing_policy_rule_get_rtm_type(const sd_netlink_message *m, unsigned char *type) { |
bce67bbe SS |
970 | struct rtmsg *routing_policy_rule; |
971 | ||
972 | assert_return(m, -EINVAL); | |
973 | assert_return(m->hdr, -EINVAL); | |
974 | assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); | |
975 | ||
976 | routing_policy_rule = NLMSG_DATA(m->hdr); | |
977 | ||
978 | *type = routing_policy_rule->rtm_type; | |
979 | ||
980 | return 0; | |
981 | } | |
982 | ||
983 | int sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char len) { | |
984 | struct rtmsg *routing_policy_rule; | |
985 | ||
986 | assert_return(m, -EINVAL); | |
987 | assert_return(m->hdr, -EINVAL); | |
988 | assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); | |
989 | ||
990 | routing_policy_rule = NLMSG_DATA(m->hdr); | |
991 | ||
992 | routing_policy_rule->rtm_dst_len = len; | |
993 | ||
994 | return 0; | |
995 | } | |
996 | ||
de157fe2 | 997 | int sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(const sd_netlink_message *m, unsigned char *len) { |
bce67bbe SS |
998 | struct rtmsg *routing_policy_rule; |
999 | ||
1000 | assert_return(m, -EINVAL); | |
1001 | assert_return(m->hdr, -EINVAL); | |
1002 | assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); | |
1003 | ||
1004 | routing_policy_rule = NLMSG_DATA(m->hdr); | |
1005 | ||
1006 | *len = routing_policy_rule->rtm_dst_len; | |
1007 | ||
1008 | return 0; | |
1009 | } | |
1010 | ||
1011 | int sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(sd_netlink_message *m, unsigned char len) { | |
1012 | struct rtmsg *routing_policy_rule; | |
1013 | ||
1014 | assert_return(m, -EINVAL); | |
1015 | assert_return(m->hdr, -EINVAL); | |
1016 | assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); | |
1017 | ||
1018 | routing_policy_rule = NLMSG_DATA(m->hdr); | |
1019 | ||
1020 | routing_policy_rule->rtm_src_len = len; | |
1021 | ||
1022 | return 0; | |
1023 | } | |
1024 | ||
de157fe2 | 1025 | int sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(const sd_netlink_message *m, unsigned char *len) { |
bce67bbe SS |
1026 | struct rtmsg *routing_policy_rule; |
1027 | ||
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); | |
1031 | ||
1032 | routing_policy_rule = NLMSG_DATA(m->hdr); | |
1033 | ||
1034 | *len = routing_policy_rule->rtm_src_len; | |
1035 | ||
1036 | return 0; | |
1037 | } | |
0f5bd7fe SS |
1038 | |
1039 | int sd_rtnl_message_new_qdisc(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int tcm_family, int tcm_ifindex) { | |
1040 | struct tcmsg *tcm; | |
1041 | int r; | |
1042 | ||
1043 | assert_return(rtnl_message_type_is_qdisc(nlmsg_type), -EINVAL); | |
1044 | assert_return(ret, -EINVAL); | |
1045 | ||
1046 | r = message_new(rtnl, ret, nlmsg_type); | |
1047 | if (r < 0) | |
1048 | return r; | |
1049 | ||
1050 | if (nlmsg_type == RTM_NEWQDISC) | |
1051 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; | |
1052 | ||
1053 | tcm = NLMSG_DATA((*ret)->hdr); | |
1054 | tcm->tcm_family = tcm_family; | |
1055 | tcm->tcm_ifindex = tcm_ifindex; | |
1056 | ||
1057 | return 0; | |
1058 | } | |
1059 | ||
1060 | int sd_rtnl_message_set_qdisc_parent(sd_netlink_message *m, uint32_t parent) { | |
1061 | struct tcmsg *tcm; | |
1062 | ||
1063 | assert_return(rtnl_message_type_is_qdisc(m->hdr->nlmsg_type), -EINVAL); | |
1064 | ||
1065 | tcm = NLMSG_DATA(m->hdr); | |
1066 | tcm->tcm_parent = parent; | |
1067 | ||
1068 | return 0; | |
1069 | } | |
1070 | ||
1071 | int sd_rtnl_message_set_qdisc_handle(sd_netlink_message *m, uint32_t handle) { | |
1072 | struct tcmsg *tcm; | |
1073 | ||
1074 | assert_return(rtnl_message_type_is_qdisc(m->hdr->nlmsg_type), -EINVAL); | |
1075 | ||
1076 | tcm = NLMSG_DATA(m->hdr); | |
1077 | tcm->tcm_handle = handle; | |
1078 | ||
1079 | return 0; | |
1080 | } | |
0ebb76de YW |
1081 | |
1082 | int sd_rtnl_message_new_tclass(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int tcm_family, int tcm_ifindex) { | |
1083 | struct tcmsg *tcm; | |
1084 | int r; | |
1085 | ||
1086 | assert_return(rtnl_message_type_is_tclass(nlmsg_type), -EINVAL); | |
1087 | assert_return(ret, -EINVAL); | |
1088 | ||
1089 | r = message_new(rtnl, ret, nlmsg_type); | |
1090 | if (r < 0) | |
1091 | return r; | |
1092 | ||
1093 | if (nlmsg_type == RTM_NEWTCLASS) | |
1094 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; | |
1095 | ||
1096 | tcm = NLMSG_DATA((*ret)->hdr); | |
1097 | tcm->tcm_family = tcm_family; | |
1098 | tcm->tcm_ifindex = tcm_ifindex; | |
1099 | ||
1100 | return 0; | |
1101 | } | |
1102 | ||
1103 | int sd_rtnl_message_set_tclass_parent(sd_netlink_message *m, uint32_t parent) { | |
1104 | struct tcmsg *tcm; | |
1105 | ||
1106 | assert_return(rtnl_message_type_is_tclass(m->hdr->nlmsg_type), -EINVAL); | |
1107 | ||
1108 | tcm = NLMSG_DATA(m->hdr); | |
1109 | tcm->tcm_parent = parent; | |
1110 | ||
1111 | return 0; | |
1112 | } | |
1113 | ||
1114 | int sd_rtnl_message_set_tclass_handle(sd_netlink_message *m, uint32_t handle) { | |
1115 | struct tcmsg *tcm; | |
1116 | ||
1117 | assert_return(rtnl_message_type_is_tclass(m->hdr->nlmsg_type), -EINVAL); | |
1118 | ||
1119 | tcm = NLMSG_DATA(m->hdr); | |
1120 | tcm->tcm_handle = handle; | |
1121 | ||
1122 | return 0; | |
1123 | } | |
1903c9bb DM |
1124 | |
1125 | int sd_rtnl_message_new_mdb(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int mdb_ifindex) { | |
1126 | struct br_port_msg *bpm; | |
1127 | int r; | |
1128 | ||
1129 | assert_return(rtnl_message_type_is_mdb(nlmsg_type), -EINVAL); | |
1130 | assert_return(ret, -EINVAL); | |
1131 | ||
1132 | r = message_new(rtnl, ret, nlmsg_type); | |
1133 | if (r < 0) | |
1134 | return r; | |
1135 | ||
1136 | if (nlmsg_type == RTM_NEWMDB) | |
1137 | (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; | |
1138 | ||
1139 | bpm = NLMSG_DATA((*ret)->hdr); | |
1140 | bpm->family = AF_BRIDGE; | |
1141 | bpm->ifindex = mdb_ifindex; | |
1142 | ||
1143 | return 0; | |
1144 | } |