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